gluttonberg-core 2.6.4 → 3.0.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 +7 -0
- data/README.md +29 -3
- data/Rakefile +32 -15
- data/app/assets/images/chosen-sprite-2x.png +0 -0
- data/app/assets/images/chosen-sprite.png +0 -0
- data/app/assets/images/{library/gb_sort_by_asc.png → gb_sort_by_asc.png} +0 -0
- data/app/assets/images/{library/gb_sort_by_desc.png → gb_sort_by_desc.png} +0 -0
- data/app/assets/javascripts/chosen-jquery-min.js +2 -0
- data/app/assets/javascripts/gb_360player.js +676 -0
- data/app/assets/javascripts/gb_application.js +708 -463
- data/app/assets/javascripts/gb_html5.js +9 -0
- data/app/assets/javascripts/gb_jeditable.js +356 -356
- data/app/assets/javascripts/gb_jquery-nestable.js +490 -0
- data/app/assets/javascripts/gb_utils.js +1808 -0
- data/app/assets/javascripts/gluttonberg.js +26 -0
- data/app/assets/javascripts/jcrop/css/gb_jquery-Jcrop.css +163 -31
- data/app/assets/javascripts/jcrop/js/jquery-Jcrop-min.js +19 -243
- data/app/assets/javascripts/jquery-1-10-1.js +6 -0
- data/app/assets/javascripts/jquery-ui-1-10-3.custom-min.js +6 -0
- data/app/assets/javascripts/jquery-validate.js +652 -718
- data/app/assets/javascripts/rails.js +372 -106
- data/app/assets/javascripts/redactormin.js +7348 -0
- data/app/assets/stylesheets/chosen.css +430 -0
- data/app/assets/stylesheets/gb_360player.css +2 -10
- data/app/assets/stylesheets/gb_admin-override.sass +466 -22
- data/app/assets/stylesheets/gb_bootstrap.css +7 -1
- data/app/assets/stylesheets/gluttonberg.css +17 -0
- data/app/assets/stylesheets/redactor.css +864 -0
- data/app/assets/stylesheets/user-styles.sass +0 -3
- data/app/controllers/gluttonberg/admin/asset_library/assets_ajax_controller.rb +65 -0
- data/app/controllers/gluttonberg/admin/asset_library/assets_bulk_controller.rb +47 -0
- data/app/controllers/gluttonberg/admin/asset_library/assets_controller.rb +43 -266
- data/app/controllers/gluttonberg/admin/asset_library/base_controller.rb +29 -0
- data/app/controllers/gluttonberg/admin/asset_library/collections_controller.rb +11 -37
- data/app/controllers/gluttonberg/admin/base_controller.rb +117 -178
- data/app/controllers/gluttonberg/admin/content/auto_save_controller.rb +63 -0
- data/app/controllers/gluttonberg/admin/content/flag_controller.rb +6 -6
- data/app/controllers/gluttonberg/admin/content/galleries_controller.rb +29 -37
- data/app/controllers/gluttonberg/admin/content/page_localizations_controller.rb +82 -49
- data/app/controllers/gluttonberg/admin/content/pages_controller.rb +59 -32
- data/app/controllers/gluttonberg/admin/main_controller.rb +77 -7
- data/app/controllers/gluttonberg/admin/membership/base_controller.rb +2 -1
- data/app/controllers/gluttonberg/admin/membership/groups_controller.rb +27 -33
- data/app/controllers/gluttonberg/admin/membership/main_controller.rb +3 -2
- data/app/controllers/gluttonberg/admin/membership/members_controller.rb +37 -42
- data/app/controllers/gluttonberg/admin/password_resets_controller.rb +16 -28
- data/app/controllers/gluttonberg/admin/settings/configurations_controller.rb +101 -0
- data/app/controllers/gluttonberg/admin/settings/embeds_controller.rb +79 -0
- data/app/controllers/gluttonberg/admin/settings/locales_controller.rb +22 -28
- data/app/controllers/gluttonberg/admin/settings/stylesheets_controller.rb +31 -36
- data/app/controllers/gluttonberg/admin/settings/users_controller.rb +45 -40
- data/app/controllers/gluttonberg/base_controller.rb +95 -0
- data/app/controllers/gluttonberg/public/base_controller.rb +104 -157
- data/app/controllers/gluttonberg/public/flag_controller.rb +2 -7
- data/app/controllers/gluttonberg/public/gallery_controller.rb +1 -0
- data/app/controllers/gluttonberg/public/member_password_resets_controller.rb +5 -17
- data/app/controllers/gluttonberg/public/members_controller.rb +5 -15
- data/app/controllers/gluttonberg/public/pages_controller.rb +25 -14
- data/app/controllers/gluttonberg/public/public_assets_controller.rb +4 -2
- data/app/helpers/gluttonberg/admin.rb +86 -368
- data/app/helpers/gluttonberg/admin/assets.rb +84 -0
- data/app/helpers/gluttonberg/admin/form.rb +159 -0
- data/app/helpers/gluttonberg/admin/messages.rb +32 -0
- data/app/helpers/gluttonberg/admin/versioning.rb +196 -0
- data/app/helpers/gluttonberg/application_helper.rb +34 -7
- data/app/helpers/gluttonberg/asset_library.rb +29 -254
- data/app/helpers/gluttonberg/content_helpers.rb +17 -69
- data/app/helpers/gluttonberg/deprecated.rb +24 -0
- data/app/helpers/gluttonberg/public.rb +51 -244
- data/app/helpers/gluttonberg/public/assets.rb +31 -0
- data/app/helpers/gluttonberg/public/cms_stylesheets.rb +35 -0
- data/app/helpers/gluttonberg/public/html_truncate.rb +74 -0
- data/app/helpers/gluttonberg/public/meta_tags.rb +27 -0
- data/app/helpers/gluttonberg/public/nav_tree.rb +99 -0
- data/app/helpers/gluttonberg/public/page_info.rb +168 -0
- data/app/mailer/gluttonberg/base_notifier.rb +25 -0
- data/app/mailer/member_notifier.rb +8 -20
- data/app/mailer/notifier.rb +14 -39
- data/app/models/ability.rb +48 -34
- data/app/models/flag.rb +7 -7
- data/app/models/gluttonberg/asset.rb +115 -166
- data/app/models/gluttonberg/asset_bulk_import.rb +70 -0
- data/app/models/gluttonberg/asset_category.rb +75 -29
- data/app/models/gluttonberg/asset_collection.rb +65 -12
- data/app/models/gluttonberg/asset_mime_type.rb +5 -0
- data/app/models/gluttonberg/asset_thumbnail.rb +6 -1
- data/app/models/gluttonberg/asset_type.rb +49 -38
- data/app/models/gluttonberg/audio_asset_attribute.rb +7 -3
- data/app/models/gluttonberg/authorization.rb +10 -0
- data/app/models/gluttonberg/auto_save.rb +32 -0
- data/app/models/gluttonberg/collapsed_page.rb +13 -0
- data/app/models/gluttonberg/embed.rb +13 -0
- data/app/models/gluttonberg/feed.rb +14 -5
- data/app/models/gluttonberg/gallery.rb +35 -9
- data/app/models/gluttonberg/gallery_image.rb +9 -2
- data/app/models/gluttonberg/group.rb +18 -2
- data/app/models/gluttonberg/html_content.rb +5 -1
- data/app/models/gluttonberg/image_content.rb +5 -1
- data/app/models/gluttonberg/locale.rb +28 -9
- data/app/models/gluttonberg/member.rb +48 -197
- data/app/models/gluttonberg/page.rb +78 -288
- data/app/models/gluttonberg/page_localization.rb +63 -66
- data/app/models/gluttonberg/plain_text_content.rb +6 -0
- data/app/models/gluttonberg/repeater.rb +30 -0
- data/app/models/gluttonberg/search.rb +96 -72
- data/app/models/gluttonberg/select_content.rb +12 -0
- data/app/models/gluttonberg/setting.rb +79 -29
- data/app/models/gluttonberg/sitemap.rb +1 -0
- data/app/models/gluttonberg/stylesheet.rb +12 -6
- data/app/models/gluttonberg/textarea_content.rb +14 -0
- data/app/models/gluttonberg/version.rb +9 -0
- data/app/models/user.rb +137 -13
- data/app/observers/gluttonberg/locale_observer.rb +33 -22
- data/app/observers/gluttonberg/page_localization_observer.rb +22 -12
- data/app/observers/gluttonberg/page_observer.rb +50 -35
- data/app/views/{gluttonberg/public/exceptions → exceptions}/access_denied.html.haml +0 -0
- data/app/views/{gluttonberg/public/exceptions → exceptions}/not_found.html.haml +0 -0
- data/app/views/gluttonberg/admin/asset_library/assets/_browser_root.html.haml +17 -12
- data/app/views/gluttonberg/admin/asset_library/assets/_form.html.haml +5 -7
- data/app/views/gluttonberg/admin/asset_library/assets/browser.html.haml +5 -5
- data/app/views/gluttonberg/admin/asset_library/assets/show.html.haml +13 -7
- data/app/views/gluttonberg/admin/asset_library/assets/show.json.rabl +3 -0
- data/app/views/gluttonberg/admin/asset_library/{assets → assets_ajax}/browser_collection.json.haml +0 -0
- data/app/views/gluttonberg/admin/asset_library/{assets → assets_bulk}/add_assets_in_bulk.html.haml +6 -20
- data/app/views/gluttonberg/admin/asset_library/{assets → assets_bulk}/create_assets_in_bulk.html.haml +0 -0
- data/app/views/gluttonberg/admin/asset_library/collections/_form.html.haml +8 -5
- data/app/views/gluttonberg/admin/asset_library/shared/_asset_browser.html.haml +34 -0
- data/app/views/gluttonberg/admin/asset_library/shared/_asset_panels.html.haml +15 -11
- data/app/views/gluttonberg/admin/content/editors/_html_content.html.haml +2 -2
- data/app/views/gluttonberg/admin/content/editors/_select_content.html.haml +7 -0
- data/app/views/gluttonberg/admin/content/editors/_textarea_content.html.haml +6 -0
- data/app/views/gluttonberg/admin/content/flag/index.html.haml +48 -39
- data/app/views/gluttonberg/admin/content/galleries/_form.html.haml +46 -9
- data/app/views/gluttonberg/admin/content/galleries/_image_repeater.html.haml +30 -0
- data/app/views/gluttonberg/admin/content/galleries/edit.html.haml +1 -12
- data/app/views/gluttonberg/admin/content/galleries/index.html.haml +18 -9
- data/app/views/gluttonberg/admin/content/galleries/new.html.haml +1 -1
- data/app/views/gluttonberg/admin/content/main/_sidebar.html.haml +28 -16
- data/app/views/gluttonberg/admin/content/page_localizations/_form.html.haml +11 -20
- data/app/views/gluttonberg/admin/content/page_localizations/edit.html.haml +7 -0
- data/app/views/gluttonberg/admin/content/pages/_form.html.haml +11 -4
- data/app/views/gluttonberg/admin/content/pages/_page_settings.html.haml +4 -7
- data/app/views/gluttonberg/admin/content/pages/_row.html.haml +38 -30
- data/app/views/gluttonberg/admin/content/pages/index.html.haml +23 -15
- data/app/views/gluttonberg/admin/content/pages/pages_list_for_tinymce.html.haml +14 -3
- data/app/views/gluttonberg/admin/content/pages/show.html.haml +1 -1
- data/app/views/gluttonberg/admin/main/index.html.haml +13 -12
- data/app/views/gluttonberg/admin/main/waiting_for_approval.html.haml +33 -0
- data/app/views/gluttonberg/admin/membership/groups/index.html.haml +5 -5
- data/app/views/gluttonberg/admin/membership/members/_form.html.haml +3 -1
- data/app/views/gluttonberg/admin/membership/members/edit.html.haml +1 -0
- data/app/views/gluttonberg/admin/membership/members/index.html.haml +1 -1
- data/app/views/gluttonberg/admin/password_resets/edit.html.haml +36 -16
- data/app/views/gluttonberg/admin/password_resets/new.html.haml +19 -11
- data/app/views/gluttonberg/admin/settings/configurations/_form.html.haml +28 -0
- data/app/views/gluttonberg/admin/settings/configurations/_settings_table.html.haml +42 -0
- data/app/views/gluttonberg/admin/settings/{generic_settings → configurations}/_value_tag.html.haml +0 -0
- data/app/views/gluttonberg/admin/settings/configurations/edit.html.haml +4 -0
- data/app/views/gluttonberg/admin/settings/configurations/index.html.haml +31 -0
- data/app/views/gluttonberg/admin/settings/{generic_settings → configurations}/new.html.haml +2 -2
- data/app/views/gluttonberg/admin/settings/embeds/_form.html.haml +19 -0
- data/app/views/gluttonberg/admin/settings/embeds/edit.html.haml +12 -0
- data/app/views/gluttonberg/admin/settings/embeds/index.html.haml +36 -0
- data/app/views/gluttonberg/admin/settings/embeds/list_for_redactor.html.haml +29 -0
- data/app/views/gluttonberg/admin/settings/embeds/new.html.haml +12 -0
- data/app/views/gluttonberg/admin/settings/locales/edit.html.haml +9 -1
- data/app/views/gluttonberg/admin/settings/locales/index.html.haml +2 -1
- data/app/views/gluttonberg/admin/settings/locales/new.html.haml +10 -1
- data/app/views/gluttonberg/admin/settings/main/_sidebar.html.haml +9 -7
- data/app/views/gluttonberg/admin/settings/stylesheets/_form.html.haml +11 -9
- data/app/views/gluttonberg/admin/settings/stylesheets/edit.html.haml +11 -2
- data/app/views/gluttonberg/admin/settings/stylesheets/index.html.haml +45 -36
- data/app/views/gluttonberg/admin/settings/stylesheets/new.html.haml +11 -2
- data/app/views/gluttonberg/admin/settings/users/_form.html.haml +29 -18
- data/app/views/gluttonberg/admin/settings/users/index.html.haml +1 -1
- data/app/views/gluttonberg/admin/shared/_asset_panel.html.haml +19 -4
- data/app/views/gluttonberg/admin/shared/_auto_save_version.html.haml +12 -0
- data/app/views/gluttonberg/admin/shared/_datetime_field.html.haml +19 -0
- data/app/views/gluttonberg/admin/shared/_previous_version_warning.html.haml +5 -0
- data/app/views/gluttonberg/admin/shared/_version_alerts.html.haml +34 -0
- data/app/views/gluttonberg/admin/shared/_version_dashboard_notifications.html.haml +11 -0
- data/app/views/gluttonberg/admin/shared/_version_listing.html.haml +23 -0
- data/app/views/gluttonberg/admin/shared/delete.html.haml +21 -48
- data/app/views/gluttonberg/admin/shared/generic.html.haml +20 -19
- data/app/views/gluttonberg/admin/user_sessions/new.html.haml +14 -9
- data/app/views/gluttonberg/public/member_password_resets/edit.html.haml +2 -0
- data/app/views/gluttonberg/public/member_password_resets/new.html.haml +3 -0
- data/app/views/gluttonberg/public/members/_form.html.haml +3 -0
- data/app/views/gluttonberg/public/members/edit.html.haml +7 -9
- data/app/views/gluttonberg/public/members/show.html.haml +1 -3
- data/app/views/gluttonberg/public/pages/restrict_site_access.html.haml +3 -4
- data/app/views/gluttonberg/public/shared/_gallery_images_lis.html.haml +9 -0
- data/app/views/layouts/_flash_messages.html.haml +5 -3
- data/app/views/layouts/bare.html.haml +8 -17
- data/app/views/layouts/gluttonberg.html.haml +37 -44
- data/app/views/notifier/version_declined.html.haml +21 -0
- data/config/locales/en_au.yml +1 -1
- data/config/locales/en_gb.yml +2 -1
- data/config/routes.rb +70 -85
- data/db/migrate/20130801050257_create_repeater.rb +14 -0
- data/lib/audio_job.rb +11 -9
- data/lib/engine.rb +115 -72
- data/lib/generators/gluttonberg/resource/resource_generator.rb +51 -41
- data/lib/generators/gluttonberg/resource/templates/admin_controller.rb +16 -11
- data/lib/generators/gluttonberg/resource/templates/backend_view_edit.html.haml +7 -2
- data/lib/generators/gluttonberg/resource/templates/backend_view_form.html.haml +3 -14
- data/lib/generators/gluttonberg/resource/templates/backend_view_import.html.haml +10 -7
- data/lib/generators/gluttonberg/resource/templates/backend_view_index.html.haml +6 -5
- data/lib/generators/gluttonberg/resource/templates/backend_view_show.html.haml +2 -2
- data/lib/generators/gluttonberg/resource/templates/migration.rb +12 -1
- data/lib/generators/gluttonberg/resource/templates/model.rb +18 -1
- data/lib/generators/gluttonberg/resource/templates/public_view_index.html.haml +27 -10
- data/lib/generators/gluttonberg/resource/templates/public_view_show.html.haml +10 -4
- data/lib/gluttonberg.rb +68 -37
- data/lib/gluttonberg/can_flag.rb +64 -76
- data/lib/gluttonberg/components.rb +47 -24
- data/lib/gluttonberg/content.rb +15 -0
- data/lib/gluttonberg/content/block.rb +99 -85
- data/lib/gluttonberg/content/block_localization.rb +11 -8
- data/lib/gluttonberg/content/clean_html.rb +12 -15
- data/lib/gluttonberg/content/default_template_file.rb +44 -0
- data/lib/gluttonberg/content/despamilator/filter/naughty_words.rb +4 -2
- data/lib/gluttonberg/content/home_page_info.rb +39 -0
- data/lib/gluttonberg/content/import_export_csv.rb +243 -130
- data/lib/gluttonberg/content/localization.rb +137 -148
- data/lib/gluttonberg/content/page_children.rb +36 -0
- data/lib/gluttonberg/content/page_components.rb +23 -0
- data/lib/gluttonberg/content/page_description_info.rb +55 -0
- data/lib/gluttonberg/content/page_duplicate.rb +68 -0
- data/lib/gluttonberg/content/page_finder.rb +63 -0
- data/lib/gluttonberg/content/page_localization_slug.rb +89 -0
- data/lib/gluttonberg/content/page_repairer.rb +117 -0
- data/lib/gluttonberg/content/publishable.rb +77 -71
- data/lib/gluttonberg/content/slug_management.rb +74 -26
- data/lib/gluttonberg/content/validations.rb +58 -0
- data/lib/gluttonberg/content/versioning.rb +40 -22
- data/lib/gluttonberg/drag_tree.rb +0 -1
- data/lib/gluttonberg/drag_tree/action_controller.rb +49 -37
- data/lib/gluttonberg/drag_tree/action_view.rb +0 -6
- data/lib/gluttonberg/drag_tree/active_record.rb +49 -49
- data/lib/gluttonberg/extensions.rb +1 -0
- data/lib/gluttonberg/extensions/string.rb +20 -0
- data/lib/gluttonberg/gb_file.rb +30 -0
- data/lib/gluttonberg/helpers/form_builder.rb +91 -38
- data/lib/gluttonberg/library.rb +9 -90
- data/lib/gluttonberg/library/attachment_mixin.rb +88 -98
- data/lib/gluttonberg/library/config/image_sizes.rb +22 -19
- data/lib/gluttonberg/library/default_asset_types.rb +104 -0
- data/lib/gluttonberg/library/processor/audio.rb +32 -16
- data/lib/gluttonberg/library/processor/image.rb +78 -69
- data/lib/gluttonberg/library/quick_magick/image.rb +72 -319
- data/lib/gluttonberg/library/quick_magick/image/draw.rb +133 -0
- data/lib/gluttonberg/library/quick_magick/image/operators_and_settings.rb +78 -0
- data/lib/gluttonberg/library/quick_magick/image/serialization.rb +79 -0
- data/lib/gluttonberg/library/quick_magick/image_list.rb +0 -1
- data/lib/gluttonberg/library/storage/filesystem.rb +45 -46
- data/lib/gluttonberg/library/storage/s3.rb +123 -119
- data/lib/gluttonberg/membership.rb +9 -0
- data/lib/gluttonberg/membership/export.rb +82 -0
- data/lib/gluttonberg/membership/import.rb +179 -0
- data/lib/gluttonberg/middleware/honeypot.rb +1 -2
- data/lib/gluttonberg/middleware/locales.rb +69 -18
- data/lib/gluttonberg/middleware/rewriter.rb +57 -16
- data/lib/gluttonberg/mixin_manager.rb +19 -0
- data/lib/gluttonberg/page_description.rb +82 -112
- data/lib/gluttonberg/random_string_generator.rb +31 -0
- data/lib/gluttonberg/record_history.rb +5 -7
- data/lib/gluttonberg/tasks/asset.rake +19 -8
- data/lib/gluttonberg/tasks/gluttonberg.rake +167 -13
- data/lib/gluttonberg/templates.rb +1 -3
- data/lib/gluttonberg/version.rb +1 -1
- data/lib/photo_job.rb +16 -0
- data/spec/controllers/auto_save_controller_spec.rb +57 -0
- data/spec/controllers/record_history_spec.rb +75 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/admin/staff_profiles_controller.rb +56 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/staff_profile.rb +20 -0
- data/spec/dummy/app/models/vendor_mixin.rb +14 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +18 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +8 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/gluttonberg_advance_settings.rb +73 -0
- data/spec/dummy/config/initializers/gluttonberg_basic_settings.rb +65 -0
- data/spec/dummy/config/initializers/gluttonberg_menu_settings.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/{lib/generators/gluttonberg/installer/templates → spec/dummy/config}/page_descriptions.rb +103 -65
- data/spec/dummy/config/routes.rb +10 -0
- data/spec/dummy/db/20130625060411_create_staff_profile.rb +35 -0
- data/spec/dummy/db/schema.rb +474 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/041/891/setting_library_number_of_recent_assets +0 -0
- data/spec/dummy/tmp/cache/08E/741/setting_comment_number_of_emails_allowed +0 -0
- data/spec/dummy/tmp/cache/580/D10/setting_title +0 -0
- data/spec/dummy/tmp/cache/62E/160/setting_fb_icon +0 -0
- data/spec/dummy/tmp/cache/6D6/FB0/setting_keywords +0 -0
- data/spec/dummy/tmp/cache/6D8/B60/setting_s3_key_id +0 -0
- data/spec/dummy/tmp/cache/6E1/A40/setting_s3_bucket +0 -0
- data/spec/dummy/tmp/cache/779/DF0/setting_from_email +0 -0
- data/spec/dummy/tmp/cache/7C5/450/setting_title_site1 +0 -0
- data/spec/dummy/tmp/cache/7C6/460/setting_title_site2 +0 -0
- data/spec/dummy/tmp/cache/802/000/setting_description +0 -0
- data/spec/dummy/tmp/cache/836/DD0/setting_backend_logo +0 -0
- data/spec/dummy/tmp/cache/862/FA0/setting_audio_assets +1 -0
- data/spec/dummy/tmp/cache/867/4E0/setting_video_assets +0 -0
- data/spec/dummy/tmp/cache/867/710/setting_enable_WYSIWYG +0 -0
- data/spec/dummy/tmp/cache/873/9E0/setting_fb_icon_site1 +0 -0
- data/spec/dummy/tmp/cache/874/9F0/setting_fb_icon_site2 +0 -0
- data/spec/dummy/tmp/cache/87D/A10/setting_s3_access_key +0 -0
- data/spec/dummy/tmp/cache/8AC/280/setting_s3_server_url +0 -0
- data/spec/dummy/tmp/cache/91B/730/setting_keywords_site1 +0 -0
- data/spec/dummy/tmp/cache/91C/740/setting_keywords_site2 +0 -0
- data/spec/dummy/tmp/cache/933/980/setting_auto_save_time +0 -0
- data/spec/dummy/tmp/cache/9BE/290/setting_from_email_site1 +0 -0
- data/spec/dummy/tmp/cache/9BF/2A0/setting_from_email_site2 +0 -0
- data/spec/dummy/tmp/cache/A02/5E0/setting_google_analytics +0 -0
- data/spec/dummy/tmp/cache/A47/800/setting_description_site1 +0 -0
- data/spec/dummy/tmp/cache/A48/810/setting_description_site2 +0 -0
- data/spec/dummy/tmp/cache/A69/B60/setting_comment_blacklist +0 -0
- data/spec/dummy/tmp/cache/B5C/D40/setting_number_of_revisions +0 -0
- data/spec/dummy/tmp/cache/BB3/350/setting_restrict_site_access +0 -0
- data/spec/dummy/tmp/cache/BB7/620/setting_comment_notification +0 -0
- data/spec/dummy/tmp/cache/BFB/140/setting_comment_email_as_spam +0 -0
- data/spec/dummy/tmp/cache/C47/DE0/setting_google_analytics_site1 +0 -0
- data/spec/dummy/tmp/cache/C48/DF0/setting_google_analytics_site2 +0 -0
- data/spec/dummy/tmp/cache/D3E/E20/setting_number_of_per_page_items +0 -0
- data/spec/dummy/tmp/cache/DF8/DB0/setting_restrict_site_access_site1 +0 -0
- data/spec/dummy/tmp/cache/DF9/DC0/setting_restrict_site_access_site2 +0 -0
- data/spec/dummy/tmp/cache/DFC/200/setting_comment_notification_site1 +0 -0
- data/spec/dummy/tmp/cache/DFD/210/setting_comment_notification_site2 +0 -0
- data/spec/dummy/tmp/cache/FD9/200/setting_comment_number_of_urls_allowed +0 -0
- data/spec/fixtures/assets/assets_import.zip +0 -0
- data/spec/fixtures/assets/audio.mp3 +0 -0
- data/spec/fixtures/assets/c3-add-interactive.mov +0 -0
- data/spec/fixtures/assets/gb_banner.jpg +0 -0
- data/spec/fixtures/assets/gb_logo.png +0 -0
- data/spec/fixtures/assets/high_res_photo.jpg +0 -0
- data/spec/fixtures/assets/untitled +0 -0
- data/spec/fixtures/members.csv +5 -0
- data/spec/fixtures/staff_profiles.csv +4 -0
- data/spec/helpers/public/assets_spec.rb +73 -0
- data/spec/helpers/public/content_helpers_spec.rb +71 -0
- data/spec/helpers/public/html_truncate_spec.rb +37 -0
- data/spec/helpers/public/meta_tags_spec.rb +29 -0
- data/spec/helpers/public/page_info_spec.rb +233 -0
- data/spec/helpers/public_spec.rb +114 -0
- data/spec/lib/content/import_export_csv_spec.rb +177 -0
- data/spec/lib/content/localization_spec.rb +107 -0
- data/spec/lib/content/page_finder_spec.rb +71 -0
- data/spec/lib/content/page_repairer_spec.rb +151 -0
- data/spec/lib/content/publishable_spec.rb +54 -0
- data/spec/lib/content/validations_spec.rb +88 -0
- data/spec/lib/drag_tree/action_controller_spec.rb +137 -0
- data/spec/lib/drag_tree/active_record_spec.rb +86 -0
- data/spec/lib/library/s3_rspec.rb +78 -0
- data/spec/lib/membership/export_spec.rb +89 -0
- data/spec/lib/membership/import_spec.rb +68 -0
- data/spec/lib/middleware/locales_spec.rb +192 -0
- data/spec/lib/middleware/rewriter_spec.rb +186 -0
- data/spec/lib/page_description_spec.rb +68 -0
- data/spec/mailers/member_notifier_spec.rb +140 -0
- data/spec/mailers/notifier_spec.rb +86 -0
- data/spec/models/asset_bulk_import_spec.rb +43 -0
- data/spec/models/asset_category_spec.rb +77 -0
- data/spec/models/asset_collection_spec.rb +72 -0
- data/spec/models/asset_spec.rb +278 -0
- data/spec/models/asset_type_spec.rb +109 -0
- data/spec/models/member_spec.rb +128 -0
- data/spec/models/page_localization_spec.rb +81 -0
- data/spec/models/page_spec.rb +221 -0
- data/spec/models/setting_spec.rb +49 -0
- data/spec/models/user_spec.rb +385 -0
- data/spec/observers/locale_observer_spec.rb +79 -0
- data/spec/observers/page_localization_observer_spec.rb +87 -0
- data/spec/observers/page_observer_spec.rb +130 -0
- data/spec/spec_helper.rb +90 -0
- metadata +508 -331
- data/app/assets/images/gb_360-button-pause-light.gif +0 -0
- data/app/assets/images/gb_360-button-pause-light.png +0 -0
- data/app/assets/images/gb_360-button-pause.gif +0 -0
- data/app/assets/images/gb_360-button-pause.png +0 -0
- data/app/assets/images/gb_360-button-play-light.gif +0 -0
- data/app/assets/images/gb_360-button-play-light.png +0 -0
- data/app/assets/images/gb_360-button-play.gif +0 -0
- data/app/assets/images/gb_360-button-play.png +0 -0
- data/app/assets/images/gb_360-button-vis-pause-light.gif +0 -0
- data/app/assets/images/gb_360-button-vis-pause-light.png +0 -0
- data/app/assets/images/gb_360-button-vis-pause.gif +0 -0
- data/app/assets/images/gb_360-button-vis-pause.png +0 -0
- data/app/assets/images/gb_360-button-vis-play-light.gif +0 -0
- data/app/assets/images/gb_360-button-vis-play-light.png +0 -0
- data/app/assets/images/gb_360-button-vis-play.gif +0 -0
- data/app/assets/images/gb_360-button-vis-play.png +0 -0
- data/app/assets/images/gb_button_bkg_grey.gif +0 -0
- data/app/assets/images/gb_icon_content_2.png +0 -0
- data/app/assets/images/gb_icon_dash.png +0 -0
- data/app/assets/images/gb_icon_library_2.png +0 -0
- data/app/assets/images/gb_page_content_fillin.gif +0 -0
- data/app/assets/images/gb_spinner_for_dialouge.gif +0 -0
- data/app/assets/images/gb_sub_nav_back_bkg.gif +0 -0
- data/app/assets/images/gb_subnav_bkg.gif +0 -0
- data/app/assets/images/gb_table_head_bkg.gif +0 -0
- data/app/assets/images/gb_wrapper_bkg.png +0 -0
- data/app/assets/images/gb_wysiwyg.png +0 -0
- data/app/assets/images/help/gb_help.jpg +0 -0
- data/app/assets/images/icons/gb_collapsed.png +0 -0
- data/app/assets/images/icons/gb_expanded.png +0 -0
- data/app/assets/images/library/gb_back.gif +0 -0
- data/app/assets/images/library/gb_dialog_overlay.png +0 -0
- data/app/assets/images/library/gb_inactive_tab.jpg +0 -0
- data/app/assets/images/library/gb_search_icon.gif +0 -0
- data/app/assets/images/library/gb_wysiwyg_pic.png +0 -0
- data/app/assets/javascripts/gb_ajaxfileupload.js +0 -205
- data/app/assets/javascripts/gb_berniecode-animator.js +0 -674
- data/app/assets/javascripts/gb_bootstrap-datepicker.js +0 -501
- data/app/assets/javascripts/gb_expander.js +0 -81
- data/app/assets/javascripts/gb_jquery-dragTree.js +0 -525
- data/app/assets/javascripts/gb_jquery-tagarea.js +0 -404
- data/app/assets/javascripts/gb_login.js +0 -33
- data/app/assets/javascripts/gb_tags.js +0 -177
- data/app/assets/javascripts/jquery-1-7-1.js +0 -9267
- data/app/assets/javascripts/jquery-dimensions-min.js +0 -12
- data/app/assets/javascripts/jquery-ui-1-8-23-custom-min.js +0 -85
- data/app/assets/javascripts/tiny_mce/jquery.tinymce.js +0 -1
- data/app/assets/javascripts/tiny_mce/langs/en.js +0 -223
- data/app/assets/javascripts/tiny_mce/plugins/advhr/css/advhr.css +0 -5
- data/app/assets/javascripts/tiny_mce/plugins/advhr/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/advhr/js/rule.js +0 -43
- data/app/assets/javascripts/tiny_mce/plugins/advhr/langs/en_dlg.js +0 -7
- data/app/assets/javascripts/tiny_mce/plugins/advhr/rule.htm +0 -58
- data/app/assets/javascripts/tiny_mce/plugins/advlink/css/advlink.css +0 -8
- data/app/assets/javascripts/tiny_mce/plugins/advlink/editor_plugin.js +0 -61
- data/app/assets/javascripts/tiny_mce/plugins/advlink/js/advlink.js +0 -564
- data/app/assets/javascripts/tiny_mce/plugins/advlink/langs/en_dlg.js +0 -54
- data/app/assets/javascripts/tiny_mce/plugins/advlink/link.htm +0 -355
- data/app/assets/javascripts/tiny_mce/plugins/advlist/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/autolink/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/fullscreen/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +0 -109
- data/app/assets/javascripts/tiny_mce/plugins/gb_assets/editor_plugin.js +0 -47
- data/app/assets/javascripts/tiny_mce/plugins/gb_assets/editor_plugin_src.js +0 -43
- data/app/assets/javascripts/tiny_mce/plugins/gb_assets/emotions.htm +0 -41
- data/app/assets/javascripts/tiny_mce/plugins/gb_assets/js/emotions.js +0 -22
- data/app/assets/javascripts/tiny_mce/plugins/gb_assets/langs/en_dlg.js +0 -20
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif +0 -0
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +0 -90
- data/app/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +0 -387
- data/app/assets/javascripts/tiny_mce/plugins/insertdatetime/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/lists/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/paste/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +0 -36
- data/app/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +0 -51
- data/app/assets/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js +0 -5
- data/app/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +0 -27
- data/app/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +0 -21
- data/app/assets/javascripts/tiny_mce/plugins/preview/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/preview/jscripts/embed.js +0 -73
- data/app/assets/javascripts/tiny_mce/plugins/preview/preview.html +0 -18
- data/app/assets/javascripts/tiny_mce/plugins/style/css/props.css +0 -13
- data/app/assets/javascripts/tiny_mce/plugins/style/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/style/js/props.js +0 -635
- data/app/assets/javascripts/tiny_mce/plugins/style/langs/en_dlg.js +0 -70
- data/app/assets/javascripts/tiny_mce/plugins/style/props.htm +0 -838
- data/app/assets/javascripts/tiny_mce/plugins/table/cell.htm +0 -180
- data/app/assets/javascripts/tiny_mce/plugins/table/css/cell.css +0 -17
- data/app/assets/javascripts/tiny_mce/plugins/table/css/row.css +0 -25
- data/app/assets/javascripts/tiny_mce/plugins/table/css/table.css +0 -13
- data/app/assets/javascripts/tiny_mce/plugins/table/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/plugins/table/js/cell.js +0 -319
- data/app/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +0 -27
- data/app/assets/javascripts/tiny_mce/plugins/table/js/row.js +0 -237
- data/app/assets/javascripts/tiny_mce/plugins/table/js/table.js +0 -450
- data/app/assets/javascripts/tiny_mce/plugins/table/langs/en_dlg.js +0 -75
- data/app/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +0 -32
- data/app/assets/javascripts/tiny_mce/plugins/table/row.htm +0 -158
- data/app/assets/javascripts/tiny_mce/plugins/table/table.htm +0 -188
- data/app/assets/javascripts/tiny_mce/plugins/wordcount/editor_plugin.js +0 -1
- data/app/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +0 -26
- data/app/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +0 -1
- data/app/assets/javascripts/tiny_mce/themes/advanced/editor_template_src.js +0 -1358
- data/app/assets/javascripts/tiny_mce/themes/advanced/img/icons.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/img/trans.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +0 -42
- data/app/assets/javascripts/tiny_mce/themes/advanced/js/link.js +0 -153
- data/app/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +0 -56
- data/app/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +0 -68
- data/app/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +0 -54
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +0 -47
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +0 -117
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
- data/app/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +0 -227
- data/app/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +0 -25
- data/app/assets/javascripts/tiny_mce/tiny_mce.js +0 -1
- data/app/assets/javascripts/tiny_mce/tiny_mce_popup.js +0 -5
- data/app/assets/javascripts/tiny_mce/utils/editable_selects.js +0 -70
- data/app/assets/javascripts/tiny_mce/utils/form_utils.js +0 -210
- data/app/assets/javascripts/tiny_mce/utils/mctabs.js +0 -162
- data/app/assets/javascripts/tiny_mce/utils/validate.js +0 -252
- data/app/controllers/gluttonberg/admin/content/articles_controller.rb +0 -139
- data/app/controllers/gluttonberg/admin/content/blogs_controller.rb +0 -101
- data/app/controllers/gluttonberg/admin/content/comments_controller.rb +0 -130
- data/app/controllers/gluttonberg/admin/content/main_controller.rb +0 -13
- data/app/controllers/gluttonberg/admin/help_controller.rb +0 -15
- data/app/controllers/gluttonberg/admin/settings/generic_settings_controller.rb +0 -90
- data/app/controllers/gluttonberg/admin/settings/main_controller.rb +0 -11
- data/app/controllers/gluttonberg/public/articles_controller.rb +0 -79
- data/app/controllers/gluttonberg/public/blogs_controller.rb +0 -44
- data/app/controllers/gluttonberg/public/comments_controller.rb +0 -46
- data/app/models/gluttonberg/article.rb +0 -73
- data/app/models/gluttonberg/article_localization.rb +0 -21
- data/app/models/gluttonberg/blog.rb +0 -19
- data/app/models/gluttonberg/comment.rb +0 -142
- data/app/models/gluttonberg/comment_subscription.rb +0 -28
- data/app/models/gluttonberg/help.rb +0 -48
- data/app/views/gluttonberg/admin/content/articles/_form.html.haml +0 -115
- data/app/views/gluttonberg/admin/content/articles/edit.html.haml +0 -11
- data/app/views/gluttonberg/admin/content/articles/index.html.haml +0 -71
- data/app/views/gluttonberg/admin/content/articles/new.html.haml +0 -11
- data/app/views/gluttonberg/admin/content/blogs/_form.html.haml +0 -56
- data/app/views/gluttonberg/admin/content/blogs/edit.html.haml +0 -3
- data/app/views/gluttonberg/admin/content/blogs/index.html.haml +0 -35
- data/app/views/gluttonberg/admin/content/blogs/new.html.haml +0 -10
- data/app/views/gluttonberg/admin/content/comments/index.html.haml +0 -66
- data/app/views/gluttonberg/admin/content/galleries/_images_list.html.haml +0 -21
- data/app/views/gluttonberg/admin/content/galleries/add_image.html.haml +0 -1
- data/app/views/gluttonberg/admin/content/main/index.html.haml +0 -20
- data/app/views/gluttonberg/admin/content/pages/edit_home.html.haml +0 -11
- data/app/views/gluttonberg/admin/exceptions/internal_server_error.html.haml +0 -11
- data/app/views/gluttonberg/admin/exceptions/not_acceptable.html.haml +0 -9
- data/app/views/gluttonberg/admin/membership/main/index.html.haml +0 -11
- data/app/views/gluttonberg/admin/settings/generic_settings/_form.html.haml +0 -26
- data/app/views/gluttonberg/admin/settings/generic_settings/edit.html.haml +0 -4
- data/app/views/gluttonberg/admin/settings/generic_settings/index.html.haml +0 -58
- data/app/views/gluttonberg/admin/settings/main/index.html.haml +0 -18
- data/app/views/gluttonberg/public/articles/index.rss.builder +0 -21
- data/app/views/gluttonberg/public/blogs/show.rss.builder +0 -21
- data/app/views/gluttonberg/public/exceptions/internal_server_error.html.haml +0 -11
- data/app/views/gluttonberg/public/exceptions/not_acceptable.html.haml +0 -9
- data/app/views/help/gluttonberg/admin/AssetLibrary/assets/add_assets_in_bulk.html.haml +0 -41
- data/app/views/help/gluttonberg/admin/AssetLibrary/assets/edit.html.haml +0 -61
- data/app/views/help/gluttonberg/admin/AssetLibrary/assets/index.html.haml +0 -16
- data/app/views/help/gluttonberg/admin/AssetLibrary/assets/new.html.haml +0 -57
- data/app/views/help/gluttonberg/admin/AssetLibrary/collections/edit.html.haml +0 -15
- data/app/views/help/gluttonberg/admin/AssetLibrary/collections/index.html.haml +0 -41
- data/app/views/help/gluttonberg/admin/AssetLibrary/collections/new.html.haml +0 -15
- data/app/views/help/gluttonberg/admin/AssetLibrary/main/index.html.haml +0 -34
- data/app/views/help/gluttonberg/admin/content/page_localizations/edit.html.haml +0 -89
- data/app/views/help/gluttonberg/admin/content/pages/_page_description_help.html.haml +0 -14
- data/app/views/help/gluttonberg/admin/content/pages/edit.html.haml +0 -62
- data/app/views/help/gluttonberg/admin/content/pages/index.html.haml +0 -111
- data/app/views/help/gluttonberg/admin/content/pages/new.html.haml +0 -61
- data/app/views/help/gluttonberg/admin/settings/dialects/edit.html.haml +0 -47
- data/app/views/help/gluttonberg/admin/settings/dialects/index.html.haml +0 -50
- data/app/views/help/gluttonberg/admin/settings/dialects/new.html.haml +0 -47
- data/app/views/help/gluttonberg/admin/settings/generic_settings/index.html.haml +0 -74
- data/app/views/help/gluttonberg/admin/settings/locales/edit.html.haml +0 -71
- data/app/views/help/gluttonberg/admin/settings/locales/index.html.haml +0 -57
- data/app/views/help/gluttonberg/admin/settings/locales/new.html.haml +0 -71
- data/app/views/help/gluttonberg/admin/settings/users/edit.html.haml +0 -63
- data/app/views/help/gluttonberg/admin/settings/users/index.html.haml +0 -60
- data/app/views/help/gluttonberg/admin/settings/users/new.html.haml +0 -69
- data/app/views/notifier/comment_notification.html.haml +0 -17
- data/app/views/notifier/comment_notification_for_admin.html.haml +0 -19
- data/db/migrate/20121106025800_add_artist_and_link_to_assets.rb +0 -6
- data/lib/acts_as_versioned.rb +0 -496
- data/lib/generators/gluttonberg/blog/blog_generator.rb +0 -46
- data/lib/generators/gluttonberg/blog/templates/articles_index.html.haml +0 -18
- data/lib/generators/gluttonberg/blog/templates/articles_show.html.haml +0 -63
- data/lib/generators/gluttonberg/blog/templates/articles_tag.html.haml +0 -24
- data/lib/generators/gluttonberg/blog/templates/blog_migration.rb +0 -90
- data/lib/generators/gluttonberg/blog/templates/blogs_index.html.haml +0 -15
- data/lib/generators/gluttonberg/blog/templates/blogs_show.html.haml +0 -25
- data/lib/generators/gluttonberg/installer/USAGE +0 -1
- data/lib/generators/gluttonberg/installer/installer_generator.rb +0 -106
- data/lib/generators/gluttonberg/installer/templates/delayed_job_script +0 -5
- data/lib/generators/gluttonberg/installer/templates/gluttonberg_migration.rb +0 -368
- data/lib/generators/gluttonberg/installer/templates/public.html.haml +0 -24
- data/lib/generators/gluttonberg/installer/templates/sitemap.rb +0 -70
- data/lib/gluttonberg/authorizable.rb +0 -51
- data/lib/gluttonberg/helpers.rb +0 -20
- data/lib/rails/railties/tasks.rake +0 -3
|
@@ -0,0 +1,1808 @@
|
|
|
1
|
+
// Utility Methods
|
|
2
|
+
function split( val ) {
|
|
3
|
+
return val.split( /,\s*/ );
|
|
4
|
+
}
|
|
5
|
+
function extractLast( term ) {
|
|
6
|
+
return split( term ).pop();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/* Very handy method to check if javascript field/variable is empty */
|
|
10
|
+
function blank(obj){
|
|
11
|
+
return obj === undefined || obj === null || obj === "null" || obj === "" || (obj.length !== undefined && obj.length <= 0) || obj == "/gray_scale_images/original/missing.png";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Add remove method to Array class for removing */
|
|
15
|
+
Array.prototype.remove= function(){
|
|
16
|
+
var what, a= arguments, L= a.length, ax;
|
|
17
|
+
while(L && this.length){
|
|
18
|
+
what= a[--L];
|
|
19
|
+
while((ax= this.indexOf(what))!= -1){
|
|
20
|
+
this.splice(ax, 1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
/* Jquery ajax file upload */
|
|
28
|
+
jQuery.extend({
|
|
29
|
+
handleError: function( s, xhr, status, e ) {
|
|
30
|
+
// If a local callback was specified, fire it
|
|
31
|
+
if ( s.error )
|
|
32
|
+
s.error( xhr, status, e );
|
|
33
|
+
// If we have some XML response text (e.g. from an AJAX call) then log it in the console
|
|
34
|
+
else if(xhr.responseText)
|
|
35
|
+
console.log(xhr.responseText);
|
|
36
|
+
},
|
|
37
|
+
createUploadIframe: function(id, uri)
|
|
38
|
+
{
|
|
39
|
+
//create frame
|
|
40
|
+
var frameId = 'jUploadFrame' + id;
|
|
41
|
+
var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';
|
|
42
|
+
if(window.ActiveXObject)
|
|
43
|
+
{
|
|
44
|
+
if(typeof uri== 'boolean'){
|
|
45
|
+
iframeHtml += ' src="' + 'javascript:false' + '"';
|
|
46
|
+
}else if(typeof uri== 'string'){
|
|
47
|
+
iframeHtml += ' src="' + uri + '"';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
iframeHtml += ' />';
|
|
51
|
+
jQuery(iframeHtml).appendTo(document.body);
|
|
52
|
+
return jQuery('#' + frameId).get(0);
|
|
53
|
+
},
|
|
54
|
+
createUploadForm: function(id, fileElementId, data)
|
|
55
|
+
{
|
|
56
|
+
//create form
|
|
57
|
+
var formId = 'jUploadForm' + id;
|
|
58
|
+
var fileId = 'jUploadFile' + id;
|
|
59
|
+
var form = jQuery('<form action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
|
|
60
|
+
if(data)
|
|
61
|
+
{
|
|
62
|
+
for(var i in data)
|
|
63
|
+
{
|
|
64
|
+
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
var oldElement = jQuery('#' + fileElementId);
|
|
68
|
+
var newElement = jQuery(oldElement).clone();
|
|
69
|
+
jQuery(oldElement).attr('id', fileId);
|
|
70
|
+
jQuery(oldElement).before(newElement);
|
|
71
|
+
jQuery(oldElement).appendTo(form);
|
|
72
|
+
|
|
73
|
+
//set attributes
|
|
74
|
+
jQuery(form).css('position', 'absolute');
|
|
75
|
+
jQuery(form).css('top', '-1200px');
|
|
76
|
+
jQuery(form).css('left', '-1200px');
|
|
77
|
+
jQuery(form).appendTo('body');
|
|
78
|
+
return form;
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
ajaxFileUpload: function(s) {
|
|
82
|
+
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
|
|
83
|
+
s = jQuery.extend({}, jQuery.ajaxSettings, s);
|
|
84
|
+
var id = new Date().getTime()
|
|
85
|
+
var form = jQuery.createUploadForm(id, s.fileElementId, (typeof(s.data)=='undefined'?false:s.data));
|
|
86
|
+
var io = jQuery.createUploadIframe(id, s.secureuri);
|
|
87
|
+
var frameId = 'jUploadFrame' + id;
|
|
88
|
+
var formId = 'jUploadForm' + id;
|
|
89
|
+
|
|
90
|
+
// Watch for a new set of requests
|
|
91
|
+
if ( s.global && ! jQuery.active++ )
|
|
92
|
+
{
|
|
93
|
+
jQuery.event.trigger( "ajaxStart" );
|
|
94
|
+
}
|
|
95
|
+
var requestDone = false;
|
|
96
|
+
// Create the request object
|
|
97
|
+
var xml = {}
|
|
98
|
+
if ( s.global )
|
|
99
|
+
jQuery.event.trigger("ajaxSend", [xml, s]);
|
|
100
|
+
// Wait for a response to come back
|
|
101
|
+
var uploadCallback = function(isTimeout)
|
|
102
|
+
{
|
|
103
|
+
var io = document.getElementById(frameId);
|
|
104
|
+
try
|
|
105
|
+
{
|
|
106
|
+
if(io.contentWindow)
|
|
107
|
+
{
|
|
108
|
+
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
|
|
109
|
+
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
|
|
110
|
+
}else if(io.contentDocument)
|
|
111
|
+
{
|
|
112
|
+
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
|
|
113
|
+
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
|
|
114
|
+
}
|
|
115
|
+
}catch(e)
|
|
116
|
+
{
|
|
117
|
+
jQuery.handleError(s, xml, null, e);
|
|
118
|
+
}
|
|
119
|
+
if ( xml || isTimeout == "timeout")
|
|
120
|
+
{
|
|
121
|
+
requestDone = true;
|
|
122
|
+
var status;
|
|
123
|
+
try {
|
|
124
|
+
status = isTimeout != "timeout" ? "success" : "error";
|
|
125
|
+
// Make sure that the request was successful or notmodified
|
|
126
|
+
if ( status != "error" )
|
|
127
|
+
{
|
|
128
|
+
// process the data (runs the xml through httpData regardless of callback)
|
|
129
|
+
var data = jQuery.uploadHttpData( xml, s.dataType );
|
|
130
|
+
// If a local callback was specified, fire it and pass it the data
|
|
131
|
+
if ( s.success )
|
|
132
|
+
s.success( data, status );
|
|
133
|
+
|
|
134
|
+
// Fire the global callback
|
|
135
|
+
if( s.global )
|
|
136
|
+
jQuery.event.trigger( "ajaxSuccess", [xml, s] );
|
|
137
|
+
} else
|
|
138
|
+
jQuery.handleError(s, xml, status);
|
|
139
|
+
} catch(e)
|
|
140
|
+
{
|
|
141
|
+
status = "error";
|
|
142
|
+
jQuery.handleError(s, xml, status, e);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// The request was completed
|
|
146
|
+
if( s.global )
|
|
147
|
+
jQuery.event.trigger( "ajaxComplete", [xml, s] );
|
|
148
|
+
|
|
149
|
+
// Handle the global AJAX counter
|
|
150
|
+
if ( s.global && ! --jQuery.active )
|
|
151
|
+
jQuery.event.trigger( "ajaxStop" );
|
|
152
|
+
|
|
153
|
+
// Process result
|
|
154
|
+
if ( s.complete )
|
|
155
|
+
s.complete(xml, status);
|
|
156
|
+
|
|
157
|
+
jQuery(io).unbind()
|
|
158
|
+
|
|
159
|
+
setTimeout(function(){
|
|
160
|
+
try
|
|
161
|
+
{
|
|
162
|
+
jQuery(io).remove();
|
|
163
|
+
jQuery(form).remove();
|
|
164
|
+
|
|
165
|
+
} catch(e)
|
|
166
|
+
{
|
|
167
|
+
jQuery.handleError(s, xml, null, e);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
}, 100)
|
|
171
|
+
|
|
172
|
+
xml = null
|
|
173
|
+
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Timeout checker
|
|
177
|
+
if ( s.timeout > 0 )
|
|
178
|
+
{
|
|
179
|
+
setTimeout(function(){
|
|
180
|
+
// Check to see if the request is still happening
|
|
181
|
+
if( !requestDone ) uploadCallback( "timeout" );
|
|
182
|
+
}, s.timeout);
|
|
183
|
+
}
|
|
184
|
+
try{
|
|
185
|
+
var form = jQuery('#' + formId);
|
|
186
|
+
jQuery(form).attr('action', s.url);
|
|
187
|
+
jQuery(form).attr('method', 'POST');
|
|
188
|
+
jQuery(form).attr('target', frameId);
|
|
189
|
+
if(form.encoding)
|
|
190
|
+
{
|
|
191
|
+
jQuery(form).attr('encoding', 'multipart/form-data');
|
|
192
|
+
}
|
|
193
|
+
else
|
|
194
|
+
{
|
|
195
|
+
jQuery(form).attr('enctype', 'multipart/form-data');
|
|
196
|
+
}
|
|
197
|
+
jQuery(form).submit();
|
|
198
|
+
|
|
199
|
+
} catch(e)
|
|
200
|
+
{
|
|
201
|
+
jQuery.handleError(s, xml, null, e);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
jQuery('#' + frameId).load(uploadCallback);
|
|
205
|
+
return {abort: function () {}};
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
uploadHttpData: function( r, type ) {
|
|
209
|
+
var data = !type;
|
|
210
|
+
data = type == "xml" || data ? r.responseXML : r.responseText;
|
|
211
|
+
// If the type is "script", eval it in global context
|
|
212
|
+
if ( type == "script" )
|
|
213
|
+
jQuery.globalEval( data );
|
|
214
|
+
// Get the JavaScript object, if JSON is used.
|
|
215
|
+
if ( type == "json" ){
|
|
216
|
+
data = data.replace('<pre style="word-wrap: break-word; white-space: pre-wrap;">' , "");
|
|
217
|
+
data = data.replace("</pre>" , "");
|
|
218
|
+
data = jQuery.parseJSON(data);
|
|
219
|
+
}
|
|
220
|
+
// evaluate scripts within html
|
|
221
|
+
if ( type == "html" )
|
|
222
|
+
jQuery("<div>").html(data).evalScripts();
|
|
223
|
+
|
|
224
|
+
return data;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
/* gb_tags */
|
|
229
|
+
|
|
230
|
+
$(document).ready(function() {
|
|
231
|
+
initStaticSingleTag("input.tag");
|
|
232
|
+
initStaticTagging("input.tags");
|
|
233
|
+
initRemoteSingleTag("input.remotetag");
|
|
234
|
+
initRemoteTagging("input.remotetags");
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
function initStaticTagging(tag_selector){
|
|
238
|
+
|
|
239
|
+
// don't navigate away from the field on tab when selecting an item
|
|
240
|
+
$( tag_selector ).bind( "keydown", function( event ) {
|
|
241
|
+
if ( event.keyCode === $.ui.keyCode.TAB &&
|
|
242
|
+
$( this ).data( "autocomplete" ).menu.active ) {
|
|
243
|
+
event.preventDefault();
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
$( tag_selector ).autocomplete({
|
|
249
|
+
source: function( request, response ) {
|
|
250
|
+
var tags = $($(this).attr('element')).attr('rel').split(",");
|
|
251
|
+
var query = extractLast(request.term).toLowerCase();
|
|
252
|
+
var matchedtags = jQuery.grep(tags, function(val, i){
|
|
253
|
+
return val.toLowerCase().search(query) >= 0 ;
|
|
254
|
+
});
|
|
255
|
+
response(matchedtags);
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
focus: function() {
|
|
259
|
+
// prevent value inserted on focus
|
|
260
|
+
return false;
|
|
261
|
+
},
|
|
262
|
+
select: selectEvent
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function initStaticSingleTag(tag_selector){
|
|
267
|
+
|
|
268
|
+
// don't navigate away from the field on tab when selecting an item
|
|
269
|
+
$( tag_selector ).bind( "keydown", function( event ) {
|
|
270
|
+
if ( event.keyCode === $.ui.keyCode.TAB &&
|
|
271
|
+
$( this ).data( "autocomplete" ).menu.active ) {
|
|
272
|
+
event.preventDefault();
|
|
273
|
+
}
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
$( tag_selector ).autocomplete({
|
|
278
|
+
source: function( request, response ) {
|
|
279
|
+
var tags = $($(this).attr('element')).attr('rel').split(",");
|
|
280
|
+
var query = request.term.toLowerCase();
|
|
281
|
+
var matchedtags = jQuery.grep(tags, function(val, i){
|
|
282
|
+
return val.toLowerCase().search(query) >= 0 ;
|
|
283
|
+
});
|
|
284
|
+
response(matchedtags);
|
|
285
|
+
},
|
|
286
|
+
|
|
287
|
+
focus: function() {
|
|
288
|
+
// prevent value inserted on focus
|
|
289
|
+
return false;
|
|
290
|
+
},
|
|
291
|
+
select: selectEventForSingle
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
var cache = {}, lastXhr;
|
|
296
|
+
|
|
297
|
+
// response of ajax should be in this format [{"id":"Management","value":"Management","label":"Management"}]
|
|
298
|
+
function initRemoteTagging(tag_selector){
|
|
299
|
+
var progress = $($( tag_selector ).attr('data-progress'));
|
|
300
|
+
|
|
301
|
+
$( tag_selector ).autocomplete({
|
|
302
|
+
minLength: 2,
|
|
303
|
+
source: function( request, response ) {
|
|
304
|
+
var term = extractLast(request.term).toLowerCase();
|
|
305
|
+
if ( term in cache ) {
|
|
306
|
+
response( cache[ term ] );
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
var url = $($(this).attr('element')).attr('rel');
|
|
310
|
+
if(progress.length >= 0){
|
|
311
|
+
progress.show();
|
|
312
|
+
}
|
|
313
|
+
lastXhr = $.ajax({
|
|
314
|
+
url: url,
|
|
315
|
+
dataType: 'json',
|
|
316
|
+
data: "term="+term,
|
|
317
|
+
complete: function(jqXHR , msg , ex){
|
|
318
|
+
var data = jQuery.parseJSON(jqXHR.responseText);
|
|
319
|
+
cache[ term ] = data;
|
|
320
|
+
if ( jqXHR === lastXhr ) {
|
|
321
|
+
response(data);
|
|
322
|
+
}
|
|
323
|
+
if(progress.length >= 0){
|
|
324
|
+
progress.hide();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
},
|
|
329
|
+
focus: function() {
|
|
330
|
+
// prevent value inserted on focus
|
|
331
|
+
return false;
|
|
332
|
+
},
|
|
333
|
+
select: selectEvent
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// response of ajax should be in this format [{"id":"Management","value":"Management","label":"Management"}]
|
|
338
|
+
function initRemoteSingleTag(tag_selector){
|
|
339
|
+
var progress = $($( tag_selector ).attr('data-progress'));
|
|
340
|
+
|
|
341
|
+
$( tag_selector ).autocomplete({
|
|
342
|
+
minLength: 2,
|
|
343
|
+
source: function( request, response ) {
|
|
344
|
+
var term = request.term.toLowerCase();
|
|
345
|
+
if ( term in cache ) {
|
|
346
|
+
response( cache[ term ] );
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
var url = $($(this).attr('element')).attr('rel');
|
|
350
|
+
if(progress.length >= 0){
|
|
351
|
+
progress.show();
|
|
352
|
+
}
|
|
353
|
+
lastXhr = $.ajax({
|
|
354
|
+
url: url,
|
|
355
|
+
dataType: 'json',
|
|
356
|
+
data: "term="+term,
|
|
357
|
+
complete: function(jqXHR , msg , ex){
|
|
358
|
+
var data = jQuery.parseJSON(jqXHR.responseText);
|
|
359
|
+
cache[ term ] = data;
|
|
360
|
+
if ( jqXHR === lastXhr ) {
|
|
361
|
+
response(data);
|
|
362
|
+
}
|
|
363
|
+
if(progress.length >= 0){
|
|
364
|
+
progress.hide();
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
},
|
|
369
|
+
focus: function() {
|
|
370
|
+
// prevent value inserted on focus
|
|
371
|
+
return false;
|
|
372
|
+
} ,
|
|
373
|
+
select: selectEventForSingle
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
function selectEvent(event, ui){
|
|
379
|
+
var terms = split( this.value );
|
|
380
|
+
// remove the current input
|
|
381
|
+
terms.pop();
|
|
382
|
+
// add the selected item
|
|
383
|
+
terms.push( ui.item.value );
|
|
384
|
+
// add placeholder to get the comma-and-space at the end
|
|
385
|
+
terms.push( "" );
|
|
386
|
+
this.value = terms.join( ", " );
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function selectEventForSingle(event, ui){
|
|
391
|
+
var target = $($( this ).attr('data-value-target'));
|
|
392
|
+
if(target.length > 0){
|
|
393
|
+
target.val(ui.item.id);
|
|
394
|
+
}
|
|
395
|
+
this.value = ui.item.value ;
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
/* gb_expander */
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
// Automatically create expanders
|
|
404
|
+
$(document).ready(function(){
|
|
405
|
+
$(".expandable").each(function(){
|
|
406
|
+
var expandable = new Expander( $(this) );
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
var Expander = function( expandable ){
|
|
411
|
+
|
|
412
|
+
var DEBUG_MODE = false;
|
|
413
|
+
var SLIDE_TIME = 300;
|
|
414
|
+
|
|
415
|
+
var thisExpandable = this;
|
|
416
|
+
|
|
417
|
+
var expandButton = $(expandable);
|
|
418
|
+
if( expandButton.length <= 0 ){
|
|
419
|
+
if( DEBUG_MODE ){
|
|
420
|
+
console.log("Expander: No expand button found.");
|
|
421
|
+
}
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
if( expandButton.length > 1 ){
|
|
425
|
+
if( DEBUG_MODE ){
|
|
426
|
+
console.log("Expander: More than one expand button found.");
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
var toggledElements = $("" + expandButton.attr("rel"));
|
|
432
|
+
if( toggledElements <= 0 ){
|
|
433
|
+
if( DEBUG_MODE ){
|
|
434
|
+
console.log("Expander: No expandable elements linked to the expand button.");
|
|
435
|
+
}
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
this.collapse = function( time ){
|
|
440
|
+
|
|
441
|
+
if( time < 0 ){
|
|
442
|
+
time = SLIDE_TIME;
|
|
443
|
+
}
|
|
444
|
+
expandButton.removeClass("expanded");
|
|
445
|
+
expandButton.addClass("collapsed");
|
|
446
|
+
toggledElements.hide();//slideUp( time );
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
this.expand = function( time ){
|
|
450
|
+
|
|
451
|
+
if( time < 0 ){
|
|
452
|
+
time = SLIDE_TIME;
|
|
453
|
+
}
|
|
454
|
+
expandButton.addClass("expanded");
|
|
455
|
+
expandButton.removeClass("collapsed");
|
|
456
|
+
toggledElements.show();//slideDown( time );
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if( expandButton.hasClass("expanded") ){
|
|
460
|
+
expandButton.removeClass("collapsed");
|
|
461
|
+
this.expand(0);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
if( expandButton.hasClass("collapsed") ){
|
|
465
|
+
this.collapse(0);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if( !expandButton.hasClass("expanded") &&
|
|
469
|
+
!expandButton.hasClass("collapsed") ){
|
|
470
|
+
this.collapse(0);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
expandButton.click( function(){
|
|
474
|
+
if( expandButton.hasClass("expanded") ){
|
|
475
|
+
thisExpandable.collapse();
|
|
476
|
+
}else{
|
|
477
|
+
thisExpandable.expand();
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
/* gb_bootstrap-datepicker */
|
|
484
|
+
/* ===========================================================
|
|
485
|
+
* bootstrap-datepicker.js v1.3.0
|
|
486
|
+
* http://twitter.github.com/bootstrap/javascript.html#datepicker
|
|
487
|
+
* ===========================================================
|
|
488
|
+
* Copyright 2011 Twitter, Inc.
|
|
489
|
+
*
|
|
490
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
491
|
+
* you may not use this file except in compliance with the License.
|
|
492
|
+
* You may obtain a copy of the License at
|
|
493
|
+
*
|
|
494
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
495
|
+
*
|
|
496
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
497
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
498
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
499
|
+
* See the License for the specific language governing permissions and
|
|
500
|
+
* limitations under the License.
|
|
501
|
+
*
|
|
502
|
+
* Contributed by Scott Torborg - github.com/storborg
|
|
503
|
+
* Loosely based on jquery.date_input.js by Jon Leighton, heavily updated and
|
|
504
|
+
* rewritten to match bootstrap javascript approach and add UI features.
|
|
505
|
+
* =========================================================== */
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
!function ( $ ) {
|
|
509
|
+
|
|
510
|
+
var selector = '[data-datepicker]',
|
|
511
|
+
all = [];
|
|
512
|
+
|
|
513
|
+
function clearDatePickers(except) {
|
|
514
|
+
var ii;
|
|
515
|
+
for(ii = 0; ii < all.length; ii++) {
|
|
516
|
+
if(all[ii] != except) {
|
|
517
|
+
all[ii].hide();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
function DatePicker( element, options ) {
|
|
523
|
+
this.$el = $(element);
|
|
524
|
+
this.proxy('show').proxy('ahead').proxy('hide').proxy('keyHandler').proxy('selectDate');
|
|
525
|
+
|
|
526
|
+
var options = $.extend({}, $.fn.bsdatepicker.defaults, options );
|
|
527
|
+
|
|
528
|
+
if((!!options.parse) || (!!options.format) || !this.detectNative()) {
|
|
529
|
+
$.extend(this, options);
|
|
530
|
+
this.$el.data('bsdatepicker', this);
|
|
531
|
+
all.push(this);
|
|
532
|
+
this.init();
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
DatePicker.prototype = {
|
|
537
|
+
|
|
538
|
+
detectNative: function(el) {
|
|
539
|
+
// Attempt to activate the native datepicker, if there is a known good
|
|
540
|
+
// one. If successful, return true. Note that input type="date"
|
|
541
|
+
// requires that the string be RFC3339, so if the format/parse methods
|
|
542
|
+
// have been overridden, this won't be used.
|
|
543
|
+
if(navigator.userAgent.match(/(iPad|iPhone); CPU(\ iPhone)? OS 5_\d/i)) {
|
|
544
|
+
// jQuery will only change the input type of a detached element.
|
|
545
|
+
var $marker = $('<span>').insertBefore(this.$el);
|
|
546
|
+
this.$el.detach().attr('type', 'date').insertAfter($marker);
|
|
547
|
+
$marker.remove();
|
|
548
|
+
return true;
|
|
549
|
+
}
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
, init: function() {
|
|
554
|
+
var $months = this.nav('months', 1);
|
|
555
|
+
var $years = this.nav('years', 12);
|
|
556
|
+
|
|
557
|
+
var $nav = $('<div>').addClass('nav').append($months, $years);
|
|
558
|
+
|
|
559
|
+
this.$month = $('.name', $months);
|
|
560
|
+
this.$year = $('.name', $years);
|
|
561
|
+
|
|
562
|
+
$calendar = $("<div>").addClass('calendar');
|
|
563
|
+
|
|
564
|
+
// Populate day of week headers, realigned by startOfWeek.
|
|
565
|
+
for (var i = 0; i < this.shortDayNames.length; i++) {
|
|
566
|
+
$calendar.append('<div class="dow">' + this.shortDayNames[(i + this.startOfWeek) % 7] + '</div>');
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
this.$days = $('<div>').addClass('days');
|
|
570
|
+
$calendar.append(this.$days);
|
|
571
|
+
|
|
572
|
+
this.$picker = $('<div>')
|
|
573
|
+
.click(function(e) { e.stopPropagation() })
|
|
574
|
+
// Use this to prevent accidental text selection.
|
|
575
|
+
.mousedown(function(e) { e.preventDefault() })
|
|
576
|
+
.addClass('datepicker')
|
|
577
|
+
.append($nav, $calendar)
|
|
578
|
+
.insertAfter(this.$el);
|
|
579
|
+
|
|
580
|
+
this.$el
|
|
581
|
+
.focus(this.show)
|
|
582
|
+
.click(this.show)
|
|
583
|
+
.change($.proxy(function() { this.selectDate(); }, this));
|
|
584
|
+
|
|
585
|
+
this.selectDate();
|
|
586
|
+
this.hide();
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
, nav: function( c, months ) {
|
|
590
|
+
var $subnav = $('<div>' +
|
|
591
|
+
'<span class="prev button">←</span>' +
|
|
592
|
+
'<span class="name"></span>' +
|
|
593
|
+
'<span class="next button">→</span>' +
|
|
594
|
+
'</div>').addClass(c)
|
|
595
|
+
$('.prev', $subnav).click($.proxy(function() { this.ahead(-months, 0) }, this));
|
|
596
|
+
$('.next', $subnav).click($.proxy(function() { this.ahead(months, 0) }, this));
|
|
597
|
+
return $subnav;
|
|
598
|
+
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
, updateName: function($area, s) {
|
|
602
|
+
// Update either the month or year field, with a background flash
|
|
603
|
+
// animation.
|
|
604
|
+
var cur = $area.find('.fg').text(),
|
|
605
|
+
$fg = $('<div>').addClass('fg').append(s);
|
|
606
|
+
$area.empty();
|
|
607
|
+
if(cur != s) {
|
|
608
|
+
var $bg = $('<div>').addClass('bg');
|
|
609
|
+
$area.append($bg, $fg);
|
|
610
|
+
$bg.fadeOut('slow', function() {
|
|
611
|
+
$(this).remove();
|
|
612
|
+
});
|
|
613
|
+
} else {
|
|
614
|
+
$area.append($fg);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
, selectMonth: function(date) {
|
|
619
|
+
var newMonth = new Date(date.getFullYear(), date.getMonth(), 1);
|
|
620
|
+
|
|
621
|
+
if (!this.curMonth || !(this.curMonth.getFullYear() == newMonth.getFullYear() &&
|
|
622
|
+
this.curMonth.getMonth() == newMonth.getMonth())) {
|
|
623
|
+
|
|
624
|
+
this.curMonth = newMonth;
|
|
625
|
+
|
|
626
|
+
var rangeStart = this.rangeStart(date), rangeEnd = this.rangeEnd(date);
|
|
627
|
+
var num_days = this.daysBetween(rangeStart, rangeEnd);
|
|
628
|
+
this.$days.empty();
|
|
629
|
+
|
|
630
|
+
for (var ii = 0; ii <= num_days; ii++) {
|
|
631
|
+
var thisDay = new Date(rangeStart.getFullYear(), rangeStart.getMonth(), rangeStart.getDate() + ii, 12, 00);
|
|
632
|
+
var $day = $('<div>').attr('date', this.format(thisDay));
|
|
633
|
+
$day.text(thisDay.getDate());
|
|
634
|
+
|
|
635
|
+
if (thisDay.getMonth() != date.getMonth()) {
|
|
636
|
+
$day.addClass('overlap');
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
this.$days.append($day);
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
this.updateName(this.$month, this.monthNames[date.getMonth()]);
|
|
643
|
+
this.updateName(this.$year, this.curMonth.getFullYear());
|
|
644
|
+
|
|
645
|
+
$('div', this.$days).click($.proxy(function(e) {
|
|
646
|
+
var $targ = $(e.target);
|
|
647
|
+
|
|
648
|
+
// The date= attribute is used here to provide relatively fast
|
|
649
|
+
// selectors for setting certain date cells.
|
|
650
|
+
this.update($targ.attr("date"));
|
|
651
|
+
|
|
652
|
+
// Don't consider this selection final if we're just going to an
|
|
653
|
+
// adjacent month.
|
|
654
|
+
if(!$targ.hasClass('overlap')) {
|
|
655
|
+
this.hide();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
}, this));
|
|
659
|
+
|
|
660
|
+
$("[date='" + this.format(new Date()) + "']", this.$days).addClass('today');
|
|
661
|
+
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
$('.selected', this.$days).removeClass('selected');
|
|
665
|
+
$('[date="' + this.selectedDateStr + '"]', this.$days).addClass('selected');
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
, selectDate: function(date) {
|
|
669
|
+
if (typeof(date) == "undefined") {
|
|
670
|
+
date = this.parse(this.$el.val());
|
|
671
|
+
};
|
|
672
|
+
if (!date) date = new Date();
|
|
673
|
+
|
|
674
|
+
this.selectedDate = date;
|
|
675
|
+
this.selectedDateStr = this.format(this.selectedDate);
|
|
676
|
+
this.selectMonth(this.selectedDate);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
, update: function(s) {
|
|
680
|
+
this.$el.val(s).change();
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
, show: function(e) {
|
|
684
|
+
e && e.stopPropagation();
|
|
685
|
+
|
|
686
|
+
// Hide all other datepickers.
|
|
687
|
+
clearDatePickers(this);
|
|
688
|
+
|
|
689
|
+
this.$picker.show();
|
|
690
|
+
|
|
691
|
+
$('html').on('keydown', this.keyHandler);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
, hide: function() {
|
|
695
|
+
this.$picker.hide();
|
|
696
|
+
$('html').off('keydown', this.keyHandler);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
, keyHandler: function(e) {
|
|
700
|
+
// Keyboard navigation shortcuts.
|
|
701
|
+
switch (e.keyCode)
|
|
702
|
+
{
|
|
703
|
+
case 9:
|
|
704
|
+
case 27:
|
|
705
|
+
// Tab or escape hides the datepicker. In this case, just return
|
|
706
|
+
// instead of breaking, so that the e doesn't get stopped.
|
|
707
|
+
this.hide(); return;
|
|
708
|
+
case 13:
|
|
709
|
+
// Enter selects the currently highlighted date.
|
|
710
|
+
this.update(this.selectedDateStr); this.hide(); break;
|
|
711
|
+
case 38:
|
|
712
|
+
// Arrow up goes to prev week.
|
|
713
|
+
this.ahead(0, -7); break;
|
|
714
|
+
case 40:
|
|
715
|
+
// Arrow down goes to next week.
|
|
716
|
+
this.ahead(0, 7); break;
|
|
717
|
+
case 37:
|
|
718
|
+
// Arrow left goes to prev day.
|
|
719
|
+
this.ahead(0, -1); break;
|
|
720
|
+
case 39:
|
|
721
|
+
// Arrow right goes to next day.
|
|
722
|
+
this.ahead(0, 1); break;
|
|
723
|
+
default:
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
e.preventDefault();
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
, parse: function(s) {
|
|
730
|
+
// Parse a partial RFC 3339 string into a Date.
|
|
731
|
+
var m;
|
|
732
|
+
if ((m = s.match(/^(\d{4,4})-(\d{2,2})-(\d{2,2})$/))) {
|
|
733
|
+
return new Date(m[1], m[2] - 1, m[3]);
|
|
734
|
+
} else {
|
|
735
|
+
return null;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
, format: function(date) {
|
|
740
|
+
// Format a Date into a string as specified by RFC 3339.
|
|
741
|
+
var month = (date.getMonth() + 1).toString(),
|
|
742
|
+
dom = date.getDate().toString();
|
|
743
|
+
if (month.length === 1) {
|
|
744
|
+
month = '0' + month;
|
|
745
|
+
}
|
|
746
|
+
if (dom.length === 1) {
|
|
747
|
+
dom = '0' + dom;
|
|
748
|
+
}
|
|
749
|
+
return date.getFullYear() + '-' + month + "-" + dom;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
, ahead: function(months, days) {
|
|
753
|
+
// Move ahead ``months`` months and ``days`` days, both integers, can be
|
|
754
|
+
// negative.
|
|
755
|
+
this.selectDate(new Date(this.selectedDate.getFullYear(),
|
|
756
|
+
this.selectedDate.getMonth() + months,
|
|
757
|
+
this.selectedDate.getDate() + days));
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
, proxy: function(meth) {
|
|
761
|
+
// Bind a method so that it always gets the datepicker instance for
|
|
762
|
+
// ``this``. Return ``this`` so chaining calls works.
|
|
763
|
+
this[meth] = $.proxy(this[meth], this);
|
|
764
|
+
return this;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
, daysBetween: function(start, end) {
|
|
768
|
+
// Return number of days between ``start`` Date object and ``end``.
|
|
769
|
+
var start = Date.UTC(start.getFullYear(), start.getMonth(), start.getDate());
|
|
770
|
+
var end = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
|
|
771
|
+
return (end - start) / 86400000;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
, findClosest: function(dow, date, direction) {
|
|
775
|
+
// From a starting date, find the first day ahead of behind it that is
|
|
776
|
+
// a given day of the week.
|
|
777
|
+
var difference = direction * (Math.abs(date.getDay() - dow - (direction * 7)) % 7);
|
|
778
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + difference);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
, rangeStart: function(date) {
|
|
782
|
+
// Get the first day to show in the current calendar view.
|
|
783
|
+
return this.findClosest(this.startOfWeek,
|
|
784
|
+
new Date(date.getFullYear(), date.getMonth()),
|
|
785
|
+
-1);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
, rangeEnd: function(date) {
|
|
789
|
+
// Get the last day to show in the current calendar view.
|
|
790
|
+
return this.findClosest((this.startOfWeek - 1) % 7,
|
|
791
|
+
new Date(date.getFullYear(), date.getMonth() + 1, 0),
|
|
792
|
+
1);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
/* DATEPICKER PLUGIN DEFINITION
|
|
797
|
+
* ============================ */
|
|
798
|
+
|
|
799
|
+
$.fn.bsdatepicker = function( options ) {
|
|
800
|
+
return this.each(function() { new DatePicker(this, options); });
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
$(function() {
|
|
804
|
+
$(selector).bsdatepicker();
|
|
805
|
+
$('html').click(clearDatePickers);
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
$.fn.bsdatepicker.DatePicker = DatePicker;
|
|
809
|
+
|
|
810
|
+
$.fn.bsdatepicker.defaults = {
|
|
811
|
+
monthNames: ["January", "February", "March", "April", "May", "June",
|
|
812
|
+
"July", "August", "September", "October", "November", "December"]
|
|
813
|
+
, shortDayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
|
814
|
+
, startOfWeek: 1
|
|
815
|
+
};
|
|
816
|
+
}( window.jQuery || window.ender );
|
|
817
|
+
|
|
818
|
+
/* Update datepicker plugin so that DD/MM/YYYY format is used. */
|
|
819
|
+
$.extend($.fn.bsdatepicker.defaults, {
|
|
820
|
+
parse: function (string) {
|
|
821
|
+
return parseStringIntoDate(string);
|
|
822
|
+
},
|
|
823
|
+
format: function (date) {
|
|
824
|
+
var
|
|
825
|
+
month = (date.getMonth() + 1).toString(),
|
|
826
|
+
dom = date.getDate().toString();
|
|
827
|
+
if (month.length === 1) {
|
|
828
|
+
month = "0" + month;
|
|
829
|
+
}
|
|
830
|
+
if (dom.length === 1) {
|
|
831
|
+
dom = "0" + dom;
|
|
832
|
+
}
|
|
833
|
+
return dom + "/" + month + "/" + date.getFullYear();
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
function parseStringIntoDate(string){
|
|
838
|
+
var matches;
|
|
839
|
+
if ((matches = string.match(/^(\d{2,2})\/(\d{2,2})\/(\d{4,4})$/))) {
|
|
840
|
+
return new Date(matches[3], matches[2]- 1, matches[1] );
|
|
841
|
+
} else {
|
|
842
|
+
return null;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function dbDateFormat(date){
|
|
847
|
+
var
|
|
848
|
+
month = (date.getMonth() + 1).toString(),
|
|
849
|
+
dom = date.getDate().toString();
|
|
850
|
+
if (month.length === 1) {
|
|
851
|
+
month = "0" + month;
|
|
852
|
+
}
|
|
853
|
+
if (dom.length === 1) {
|
|
854
|
+
dom = "0" + dom;
|
|
855
|
+
}
|
|
856
|
+
return date.getFullYear() + "-"+ month + "-" + dom ;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
function combine_datetime(target_field_class){
|
|
860
|
+
var src_date_field = $("#"+target_field_class + "_date");
|
|
861
|
+
var src_time_field = $("#"+target_field_class + "_time");
|
|
862
|
+
var date = parseStringIntoDate(src_date_field.val());
|
|
863
|
+
var time = src_time_field.val();
|
|
864
|
+
|
|
865
|
+
if(time == "" || time.split(":").length !=2 ){
|
|
866
|
+
time = "00:00"
|
|
867
|
+
}else{
|
|
868
|
+
var hours = parseInt(time.split(":")[0] , 10);
|
|
869
|
+
var secondpart = time.split(":")[1];
|
|
870
|
+
var minutes = 0;
|
|
871
|
+
var am_pm = "AM";
|
|
872
|
+
|
|
873
|
+
if(secondpart.search(" ") > 0){
|
|
874
|
+
minutes = parseInt(secondpart.split(" ")[0],10);
|
|
875
|
+
am_pm = secondpart.split(" ")[1];
|
|
876
|
+
}else{
|
|
877
|
+
minutes = parseInt(secondpart.substring(0,2),10);
|
|
878
|
+
am_pm = secondpart.substring(2);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
if((am_pm.toLowerCase() == "am" || am_pm.toLowerCase() == "") && hours == 12){
|
|
882
|
+
hours = 0
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
if(am_pm.toLowerCase() == "pm" && hours != 12){
|
|
886
|
+
hours += 12;
|
|
887
|
+
}else{
|
|
888
|
+
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if(hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59){
|
|
892
|
+
time = hours + ":"+ minutes;
|
|
893
|
+
}else{
|
|
894
|
+
time = "00:00";
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
var new_val = "";
|
|
901
|
+
if(date != null){
|
|
902
|
+
new_val = dbDateFormat(date) + " " + time;
|
|
903
|
+
|
|
904
|
+
}
|
|
905
|
+
$("."+target_field_class).val(new_val);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function checkDateFormat(datefield,error_label){
|
|
909
|
+
date = $(datefield).val();
|
|
910
|
+
error_label = $(error_label)
|
|
911
|
+
// regular expression to match required date format
|
|
912
|
+
re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
|
|
913
|
+
|
|
914
|
+
if(date != '') {
|
|
915
|
+
if(regs = date.match(re)) {
|
|
916
|
+
// day value between 1 and 31
|
|
917
|
+
if(regs[1] < 1 || regs[1] > 31) {
|
|
918
|
+
show_validation_error(error_label ,"Invalid value for day: " + regs[1]);
|
|
919
|
+
datefield.focus();
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
// month value between 1 and 12
|
|
923
|
+
if(regs[2] < 1 || regs[2] > 12) {
|
|
924
|
+
show_validation_error(error_label ,"Invalid value for month: " + regs[2]);
|
|
925
|
+
datefield.focus();
|
|
926
|
+
return false;
|
|
927
|
+
}
|
|
928
|
+
// year value between 1902 and 2012
|
|
929
|
+
if(regs[3] < 1902 || regs[3] > (new Date()).getFullYear()+2) {
|
|
930
|
+
show_validation_error(error_label ,"Invalid value for year: " + regs[3] + " - must be between 1902 and " + (new Date()).getFullYear()+2);
|
|
931
|
+
datefield.focus();
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
} else {
|
|
935
|
+
show_validation_error(error_label ,"Invalid date format: " + date);
|
|
936
|
+
datefield.focus();
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
error_label.html('');
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
function checkTimeFormat(timeField,error_label)
|
|
944
|
+
{
|
|
945
|
+
time = $(timeField).val();
|
|
946
|
+
error_label = $(error_label)
|
|
947
|
+
// regular expression to match required time format
|
|
948
|
+
re = /^(\d{1,2}):(\d{2})(\s){0,1}([a|p]m)?$/i;
|
|
949
|
+
|
|
950
|
+
if(!blank(time)) {
|
|
951
|
+
if(regs = time.match(re)) {
|
|
952
|
+
if(regs[3]) {
|
|
953
|
+
// 12-hour value between 1 and 12
|
|
954
|
+
if(regs[1] < 1 || regs[1] > 12) {
|
|
955
|
+
show_validation_error(error_label ,"Invalid value for hours: " + regs[1]);
|
|
956
|
+
timeField.focus();
|
|
957
|
+
return false;
|
|
958
|
+
}
|
|
959
|
+
} else {
|
|
960
|
+
// 12-hour value between 1 and 12
|
|
961
|
+
if(regs[1] < 1 || regs[1] > 12) {
|
|
962
|
+
show_validation_error(error_label ,"Invalid value for hours: " + regs[1]);
|
|
963
|
+
timeField.focus();
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
// minute value between 0 and 59
|
|
968
|
+
if(regs[2] > 59) {
|
|
969
|
+
show_validation_error(error_label ,"Invalid value for minutes: " + regs[2]);
|
|
970
|
+
timeField.focus();
|
|
971
|
+
return false;
|
|
972
|
+
}
|
|
973
|
+
} else {
|
|
974
|
+
show_validation_error(error_label ,"Invalid time format: " + timeField.value);
|
|
975
|
+
timeField.focus();
|
|
976
|
+
return false;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
error_label.html('');
|
|
981
|
+
return true;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
function show_validation_error(error_label , message){
|
|
985
|
+
error_label.html(message);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
/* gb_jquery-dragTree */
|
|
991
|
+
/*
|
|
992
|
+
*
|
|
993
|
+
* jQuery dragTree Plugin 2.0. Built for Gluttonberg CMS system
|
|
994
|
+
*
|
|
995
|
+
*
|
|
996
|
+
* Orginal treetable code based onjQuery treeTable Plugin 2.1 -
|
|
997
|
+
* http://ludo.cubicphuse.nl/jquery-plugins/treeTable/
|
|
998
|
+
* The orginal code has been significantly modified.
|
|
999
|
+
*
|
|
1000
|
+
*
|
|
1001
|
+
* Call dragTreeManager.init() in your Javaascript once to initialise all
|
|
1002
|
+
* Drag Trees
|
|
1003
|
+
*
|
|
1004
|
+
* To make a table into a DragTree you need to do the following:
|
|
1005
|
+
* - set the CSS class of the table to "drag-tree"
|
|
1006
|
+
* - set the CSS of the element in the cell that is to be used for
|
|
1007
|
+
* dragging to drag-node
|
|
1008
|
+
*
|
|
1009
|
+
* - during drag operations the following CSS classes are applied
|
|
1010
|
+
* to the tr of the target row:
|
|
1011
|
+
* "insert_child": when mouse if over the row and the source will be made a child of the target
|
|
1012
|
+
* "insert_before": when mouse is at the "top" part of the target row and source will be insert before this row
|
|
1013
|
+
* "insert_after": when mouse id at the "bottom" part of the target row and source will be inserted after (or as child) of this row
|
|
1014
|
+
*
|
|
1015
|
+
* - Set each tr in the table to have a CSS ID of
|
|
1016
|
+
* "node-<x>" where <x> is a unique integer value
|
|
1017
|
+
*
|
|
1018
|
+
* - To make a tree set a row's css to the following class
|
|
1019
|
+
* "child-of-<x>" where <x> is the number assigned to the
|
|
1020
|
+
* nodes parent in the CSS ID "node-<x>"
|
|
1021
|
+
*
|
|
1022
|
+
*/
|
|
1023
|
+
|
|
1024
|
+
(function($) {
|
|
1025
|
+
// Helps to make options available to all functions
|
|
1026
|
+
// TODO: This gives problems when there are both expandable and non-expandable
|
|
1027
|
+
// trees on a page. The options shouldn't be global to all these instances!
|
|
1028
|
+
var options;
|
|
1029
|
+
|
|
1030
|
+
$.fn.treeTable = function(opts) {
|
|
1031
|
+
options = $.extend({}, $.fn.treeTable.defaults, opts);
|
|
1032
|
+
|
|
1033
|
+
return this.each(function() {
|
|
1034
|
+
$(this).addClass("treeTable").find("tbody tr").each(function() {
|
|
1035
|
+
// Initialize root nodes only whenever possible
|
|
1036
|
+
if(!options.expandable || $(this)[0].className.search("child-of-") == -1) {
|
|
1037
|
+
initialize($(this));
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
});
|
|
1041
|
+
};
|
|
1042
|
+
|
|
1043
|
+
$.fn.treeTable.defaults = {
|
|
1044
|
+
childPrefix: "child-of-",
|
|
1045
|
+
expandable: true,
|
|
1046
|
+
indent: 19,
|
|
1047
|
+
initialState: "collapsed",
|
|
1048
|
+
treeColumn: 0
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
// Recursively hide all node's children in a tree
|
|
1052
|
+
$.fn.collapse_recursive = function() {
|
|
1053
|
+
$(this).addClass("collapsed");
|
|
1054
|
+
|
|
1055
|
+
childrenOf($(this)).each(function() {
|
|
1056
|
+
if(!$(this).hasClass("collapsed")) {
|
|
1057
|
+
$(this).collapse_recursive();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
$(this).hide();
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
return this;
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
// Recursively show all node's children in a tree
|
|
1067
|
+
$.fn.expand = function() {
|
|
1068
|
+
$(this).removeClass("collapsed").addClass("expanded");
|
|
1069
|
+
|
|
1070
|
+
childrenOf($(this)).each(function() {
|
|
1071
|
+
initialize($(this));
|
|
1072
|
+
|
|
1073
|
+
if($(this).is(".expanded.parent")) {
|
|
1074
|
+
$(this).expand();
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
$(this).show();
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
return this;
|
|
1081
|
+
};
|
|
1082
|
+
|
|
1083
|
+
// Add an entire branch to +destination+
|
|
1084
|
+
$.fn.appendBranchTo = function(destination, success_callback) {
|
|
1085
|
+
var node = $(this);
|
|
1086
|
+
var parent = parentOf(node);
|
|
1087
|
+
|
|
1088
|
+
var ancestorNames = $.map(ancestorsOf($(destination)), function(a) { return a.id; });
|
|
1089
|
+
|
|
1090
|
+
// Conditions:
|
|
1091
|
+
// 1: +node+ should not be inserted in a location in a branch if this would
|
|
1092
|
+
// result in +node+ being an ancestor of itself.
|
|
1093
|
+
// 2: +node+ should not have a parent OR the destination should not be the
|
|
1094
|
+
// same as +node+'s current parent (this last condition prevents +node+
|
|
1095
|
+
// from being moved to the same location where it already is).
|
|
1096
|
+
// 3: +node+ should not be inserted as a child of +node+ itself.
|
|
1097
|
+
if($.inArray(node[0].id, ancestorNames) == -1 && (!parent || (destination.id != parent[0].id)) && destination.id != node[0].id) {
|
|
1098
|
+
indent(node, ancestorsOf(node).length * options.indent * -1); // Remove indentation
|
|
1099
|
+
|
|
1100
|
+
if(parent) { node.removeClass(options.childPrefix + parent[0].id); }
|
|
1101
|
+
|
|
1102
|
+
node.addClass(options.childPrefix + destination.id);
|
|
1103
|
+
move(node, destination); // Recursively move nodes to new location
|
|
1104
|
+
indent(node, ancestorsOf(node).length * options.indent);
|
|
1105
|
+
|
|
1106
|
+
if (success_callback) {
|
|
1107
|
+
success_callback.call();
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
return this;
|
|
1112
|
+
};
|
|
1113
|
+
|
|
1114
|
+
$.fn.insertBranchAfter = function(destination, success_callback) {
|
|
1115
|
+
insertBranchBeforeOrAfter(this, destination, false, success_callback);
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
$.fn.insertBranchBefore = function(destination, success_callback) {
|
|
1119
|
+
insertBranchBeforeOrAfter(this, destination, true, success_callback);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// Add reverse() function from JS Arrays
|
|
1123
|
+
$.fn.reverse = function() {
|
|
1124
|
+
return this.pushStack(this.get().reverse(), arguments);
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
// Toggle an entire branch
|
|
1128
|
+
$.fn.toggleBranch = function() {
|
|
1129
|
+
if($(this).hasClass("collapsed")) {
|
|
1130
|
+
$(this).expand();
|
|
1131
|
+
} else {
|
|
1132
|
+
$(this).removeClass("expanded").collapse_recursive();
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
return this;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// === Private functions
|
|
1139
|
+
|
|
1140
|
+
insertBranchBeforeOrAfter = function(source, destination, before, success_callback) {
|
|
1141
|
+
var sourceNode = $(source);
|
|
1142
|
+
var targetNode = $(destination);
|
|
1143
|
+
var targetParent = undefined;
|
|
1144
|
+
|
|
1145
|
+
// if we are inserting after a node and that node has children, we are actually
|
|
1146
|
+
// reparenting to that node.
|
|
1147
|
+
if (!before && hasChildren(targetNode)){
|
|
1148
|
+
targetParent = targetNode;
|
|
1149
|
+
} else {
|
|
1150
|
+
targetParent = parentOf(targetNode);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
var sourceParent = parentOf(sourceNode);
|
|
1154
|
+
var needsIndenting = false;
|
|
1155
|
+
|
|
1156
|
+
if(nodeNotInDestinationAncestry(sourceNode, targetNode) && nodesDifferent(targetNode, sourceNode)) {
|
|
1157
|
+
if (nodesDifferent(sourceParent, targetParent)){
|
|
1158
|
+
// The nodes have different parents so reparent the node
|
|
1159
|
+
indent(sourceNode, ancestorsOf(sourceNode).length * options.indent * -1); // Remove indentation
|
|
1160
|
+
needsIndenting = true;
|
|
1161
|
+
if (sourceParent) {sourceNode.removeClass(options.childPrefix + sourceParent[0].id); }
|
|
1162
|
+
if (targetParent) {sourceNode.addClass(options.childPrefix + targetParent[0].id);}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// move node
|
|
1166
|
+
if (before) {
|
|
1167
|
+
moveBefore(sourceNode, destination); // Recursively move nodes to new location
|
|
1168
|
+
} else {
|
|
1169
|
+
move(sourceNode, destination); // Recursively move nodes to new location
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (needsIndenting){
|
|
1173
|
+
// the parent was changed so re-apply indentation
|
|
1174
|
+
indent(sourceNode, ancestorsOf(sourceNode).length * options.indent);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
if (success_callback) {
|
|
1178
|
+
success_callback.call();
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
return this;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
function nodeNotInDestinationAncestry(node, destination){
|
|
1185
|
+
var ancestorNames = $.map(ancestorsOf(destination), function(a) { return a.id; });
|
|
1186
|
+
return $.inArray(node[0].id, ancestorNames) == -1;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function nodesSame(nodeA, nodeB){
|
|
1190
|
+
if (nodeA && nodeB){
|
|
1191
|
+
return (nodeA[0].id == nodeB[0].id);
|
|
1192
|
+
} else {
|
|
1193
|
+
return (nodeA == nodeB)
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
function nodesDifferent(nodeA, nodeB){
|
|
1198
|
+
return !(nodesSame(nodeA, nodeB));
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
function ancestorsOf(node) {
|
|
1202
|
+
var ancestors = [];
|
|
1203
|
+
while(node = parentOf(node)) {
|
|
1204
|
+
ancestors[ancestors.length] = node[0];
|
|
1205
|
+
}
|
|
1206
|
+
return ancestors;
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
function childrenOf(node) {
|
|
1210
|
+
return $("table.treeTable tbody tr." + options.childPrefix + node[0].id);
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
function indent(node, value) {
|
|
1214
|
+
var cell = $(node.children("td")[options.treeColumn]);
|
|
1215
|
+
var padding = parseInt(cell.css("padding-left"), 10) + value;
|
|
1216
|
+
|
|
1217
|
+
cell.css("padding-left", + padding + "px");
|
|
1218
|
+
|
|
1219
|
+
childrenOf(node).each(function() {
|
|
1220
|
+
indent($(this), value);
|
|
1221
|
+
});
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1224
|
+
function hasChildren(node){
|
|
1225
|
+
var childNodes = childrenOf(node);
|
|
1226
|
+
return childNodes.length > 0;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
function initialize(node) {
|
|
1230
|
+
if(!node.hasClass("initialized")) {
|
|
1231
|
+
node.addClass("initialized");
|
|
1232
|
+
|
|
1233
|
+
var childNodes = childrenOf(node);
|
|
1234
|
+
|
|
1235
|
+
if(!node.hasClass("parent") && childNodes.length > 0) {
|
|
1236
|
+
node.addClass("parent");
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
if(node.hasClass("parent")) {
|
|
1240
|
+
var cell = $(node.children("td")[options.treeColumn]);
|
|
1241
|
+
var padding = parseInt(cell.css("padding-left"), 10) + options.indent;
|
|
1242
|
+
|
|
1243
|
+
childNodes.each(function() {
|
|
1244
|
+
$($(this).children("td")[options.treeColumn]).css("padding-left", padding + "px");
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
if(options.expandable) {
|
|
1248
|
+
cell.prepend('<span style="margin-left: -' + options.indent + 'px; padding-left: ' + options.indent + 'px" class="expander"></span>');
|
|
1249
|
+
$(cell[0].firstChild).click(function() { node.toggleBranch(); });
|
|
1250
|
+
|
|
1251
|
+
// Check for a class set explicitly by the user, otherwise set the default class
|
|
1252
|
+
if(!(node.hasClass("expanded") || node.hasClass("collapsed"))) {
|
|
1253
|
+
node.addClass(options.initialState);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
if(node.hasClass("collapsed")) {
|
|
1257
|
+
node.collapse_recursive();
|
|
1258
|
+
} else if (node.hasClass("expanded")) {
|
|
1259
|
+
node.expand();
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
function move(node, destination) {
|
|
1267
|
+
node.insertAfter(destination);
|
|
1268
|
+
childrenOf(node).reverse().each(function() { move($(this), node[0]); });
|
|
1269
|
+
};
|
|
1270
|
+
|
|
1271
|
+
function moveBefore(node, destination) {
|
|
1272
|
+
node.insertBefore(destination);
|
|
1273
|
+
childrenOf(node).reverse().each(function() { move($(this), node[0]); });
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
function parentOf(node) {
|
|
1277
|
+
var classNames = node[0].className.split(' ');
|
|
1278
|
+
for(key = 0 ; key < classNames.length ; key++) {
|
|
1279
|
+
if(classNames[key].match("child-of-")) {
|
|
1280
|
+
return $("#" + classNames[key].substring(9));
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
};
|
|
1284
|
+
})(jQuery);
|
|
1285
|
+
|
|
1286
|
+
DM_NONE = null;
|
|
1287
|
+
DM_INSERT_BEFORE = {};
|
|
1288
|
+
DM_INSERT_AFTER = {};
|
|
1289
|
+
DM_INSERT_CHILD = {};
|
|
1290
|
+
|
|
1291
|
+
var dragTreeManager = {
|
|
1292
|
+
init: function(){
|
|
1293
|
+
|
|
1294
|
+
var dragManager = {
|
|
1295
|
+
dropSite: null,
|
|
1296
|
+
dragMode: DM_NONE
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
// Look for all tables with a class of 'drag_tree' and make them
|
|
1300
|
+
// into dragtrees
|
|
1301
|
+
$(".drag-tree").each(function(index){
|
|
1302
|
+
|
|
1303
|
+
var dragTree = $(this);
|
|
1304
|
+
|
|
1305
|
+
var dragFlat = $(this).hasClass('drag-flat');
|
|
1306
|
+
|
|
1307
|
+
try{
|
|
1308
|
+
dragTree.treeTable({expandable: false});
|
|
1309
|
+
}catch(e){
|
|
1310
|
+
console.log(e);
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
var remote_move_node = function(source, destination, mode){
|
|
1315
|
+
|
|
1316
|
+
var ids = get_sorted_element_ids(dragTree).toString();
|
|
1317
|
+
$.ajax({
|
|
1318
|
+
type: "POST",
|
|
1319
|
+
url: dragTree.attr("rel"),
|
|
1320
|
+
data: "element_ids=" + ids,
|
|
1321
|
+
beforeSend: function(jqXHR, settings){
|
|
1322
|
+
showOverlay();
|
|
1323
|
+
},
|
|
1324
|
+
success: function(html){
|
|
1325
|
+
window.setTimeout(function(){
|
|
1326
|
+
hideOverlay();
|
|
1327
|
+
},500)
|
|
1328
|
+
},
|
|
1329
|
+
error: function(html){
|
|
1330
|
+
|
|
1331
|
+
$("#assetsDialogOverlay").html(html.responseText);
|
|
1332
|
+
window.setTimeout(function(){
|
|
1333
|
+
hideOverlay();
|
|
1334
|
+
},10000)
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
}
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// Configure draggable rows
|
|
1344
|
+
try{
|
|
1345
|
+
dragTree.find(".drag-node").draggable({
|
|
1346
|
+
helper: "clone",
|
|
1347
|
+
opacity: .75,
|
|
1348
|
+
revert: "invalid",
|
|
1349
|
+
revertDuration: 300,
|
|
1350
|
+
scroll: true,
|
|
1351
|
+
drag: function(e, ui){
|
|
1352
|
+
if (dragManager.dropSite) {
|
|
1353
|
+
var top = dragManager.dropSite.offset().top ;
|
|
1354
|
+
var height = dragManager.dropSite.height();
|
|
1355
|
+
|
|
1356
|
+
var mouseTop = e.pageY;
|
|
1357
|
+
var topOffset = 10;
|
|
1358
|
+
var bottomOffset = 10;
|
|
1359
|
+
|
|
1360
|
+
if (dragFlat) {
|
|
1361
|
+
topOffset = height / 2;
|
|
1362
|
+
bottomOffset = height / 2;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
dragTree.find("#"+$(this).attr('rel')).addClass("ui-draggable-dragging")
|
|
1366
|
+
|
|
1367
|
+
if( dragManager.dropSite.attr('id') != $(this).attr('rel')){
|
|
1368
|
+
if (mouseTop < (top + topOffset)){
|
|
1369
|
+
dragManager.dropSite.addClass("insert_before").removeClass("insert_child insert_after");
|
|
1370
|
+
dragManager.dragMode = DM_INSERT_BEFORE;
|
|
1371
|
+
} else if (mouseTop > (top + height - bottomOffset)) {
|
|
1372
|
+
dragManager.dropSite.addClass("insert_after").removeClass("insert_before insert_child");
|
|
1373
|
+
dragManager.dragMode = DM_INSERT_AFTER;
|
|
1374
|
+
} else {
|
|
1375
|
+
if (!dragFlat){
|
|
1376
|
+
dragManager.dropSite.addClass("insert_child").removeClass("insert_after insert_before");
|
|
1377
|
+
dragManager.dragMode = DM_INSERT_CHILD;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
}else{//self node check
|
|
1381
|
+
dragManager.dropSite.removeClass("insert_child insert_after insert_before");
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
});
|
|
1386
|
+
|
|
1387
|
+
}catch(e){
|
|
1388
|
+
console.log(e);
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
|
|
1392
|
+
try{
|
|
1393
|
+
// Configure droppable rows
|
|
1394
|
+
dragTree.find(".drag-node").each(function() {
|
|
1395
|
+
$(this).parents("tr").droppable({
|
|
1396
|
+
accept: ".drag-node:not(selected)",
|
|
1397
|
+
drop: function(e, ui) {
|
|
1398
|
+
|
|
1399
|
+
var sourceNode = $(ui.draggable).parents("tr")
|
|
1400
|
+
var targetNode = this;
|
|
1401
|
+
|
|
1402
|
+
sourceNode.removeClass("ui-draggable-dragging")
|
|
1403
|
+
|
|
1404
|
+
if ((dragManager.dragMode == DM_INSERT_CHILD) && (!dragFlat)) {
|
|
1405
|
+
$(sourceNode).appendBranchTo(targetNode,
|
|
1406
|
+
function(){
|
|
1407
|
+
remote_move_node(sourceNode, targetNode, 'INSERT');
|
|
1408
|
+
}
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
if (dragManager.dragMode == DM_INSERT_BEFORE) {
|
|
1412
|
+
$(sourceNode).insertBranchBefore(targetNode,
|
|
1413
|
+
function(){
|
|
1414
|
+
remote_move_node(sourceNode, targetNode, 'BEFORE');
|
|
1415
|
+
}
|
|
1416
|
+
);
|
|
1417
|
+
}
|
|
1418
|
+
if (dragManager.dragMode == DM_INSERT_AFTER) {
|
|
1419
|
+
$(sourceNode).insertBranchAfter(targetNode,
|
|
1420
|
+
function(){
|
|
1421
|
+
remote_move_node(sourceNode, targetNode, 'AFTER');
|
|
1422
|
+
}
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
$(sourceNode).effect("highlight", {}, 2000);
|
|
1427
|
+
dragTree.find("tr").removeClass("insert_child insert_before insert_after");
|
|
1428
|
+
dragManager.dropSite = null;
|
|
1429
|
+
dragManager.dragMode = DM_NONE;
|
|
1430
|
+
},
|
|
1431
|
+
hoverClass: "accept",
|
|
1432
|
+
over: function(e, ui) {
|
|
1433
|
+
|
|
1434
|
+
element = $(this); //ui.draggable.parent();
|
|
1435
|
+
|
|
1436
|
+
if (element.parents("tr") != dragManager.dropSite) {
|
|
1437
|
+
dragManager.dropSite = element;
|
|
1438
|
+
}
|
|
1439
|
+
// Make the droppable branch expand when a draggable node is moved over it.
|
|
1440
|
+
if(this.id != ui.draggable.parents("tr")[0].id && !$(this).is(".expanded")) {
|
|
1441
|
+
$(this).expand();
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
out: function(e, ui){
|
|
1445
|
+
element = $(this);
|
|
1446
|
+
element.removeClass("insert_child insert_before insert_after");
|
|
1447
|
+
if (dragManager.dropSite == element) {
|
|
1448
|
+
dragManager.dropSite = null;
|
|
1449
|
+
dragManager.dragMode = DM_NONE;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
});
|
|
1454
|
+
|
|
1455
|
+
}catch(e){
|
|
1456
|
+
console.log(e);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
// Make visible that a row is clicked
|
|
1460
|
+
dragTree.find("tbody tr").mousedown(function() {
|
|
1461
|
+
$("tr.selected").removeClass("selected"); // Deselect currently selected rows
|
|
1462
|
+
$(this).addClass("selected");
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
// Make sure row is selected when span is clicked
|
|
1466
|
+
dragTree.find("tbody tr span").mousedown(function() {
|
|
1467
|
+
$($(this).parents("tr")[0]).trigger("mousedown");
|
|
1468
|
+
});
|
|
1469
|
+
});
|
|
1470
|
+
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
// it take ids of all ".orderable-list-item" inside container (wrapper_id)
|
|
1475
|
+
// and returns array of all ids
|
|
1476
|
+
function get_sorted_element_ids(wrapper)
|
|
1477
|
+
{
|
|
1478
|
+
try{
|
|
1479
|
+
var items = wrapper.find("tbody tr.ui-droppable");
|
|
1480
|
+
items = $.map(items, function(value){
|
|
1481
|
+
return value.id.replace("node-","");
|
|
1482
|
+
});
|
|
1483
|
+
return items;
|
|
1484
|
+
}catch(e){}
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
|
|
1488
|
+
function showOverlay() {
|
|
1489
|
+
if ($("#assetsDialogOverlay").length == 0) {
|
|
1490
|
+
var height = $('#wrapper').height() + 50;
|
|
1491
|
+
AssetBrowser.overlay = $('<div id="assetsDialogOverlay" class="modal-backdrop"><div class="progress progress-striped active"><div class="bar" style="width: 100%;"></div></div></div>');
|
|
1492
|
+
$("body").append(AssetBrowser.overlay);
|
|
1493
|
+
}
|
|
1494
|
+
else {
|
|
1495
|
+
$("#assetsDialogOverlay").css({
|
|
1496
|
+
display: "block"
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
set_height = wrapper_height = $("body").height();
|
|
1500
|
+
window_height = $(window).height() + $(window).scrollTop()
|
|
1501
|
+
if(set_height < window_height)
|
|
1502
|
+
set_height = window_height;
|
|
1503
|
+
$("#assetsDialogOverlay").height( set_height )
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
function hideOverlay(){
|
|
1507
|
+
$("#assetsDialogOverlay").remove();
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
|
|
1511
|
+
/* Redactor gluttonberg plugins */
|
|
1512
|
+
if (typeof RedactorPlugins === 'undefined') var RedactorPlugins = {};
|
|
1513
|
+
|
|
1514
|
+
RedactorPlugins.asset_library_image = {
|
|
1515
|
+
|
|
1516
|
+
init: function()
|
|
1517
|
+
{
|
|
1518
|
+
this.buttonAddBefore('video', 'asset_library_image', 'Insert image', function()
|
|
1519
|
+
{
|
|
1520
|
+
this.selectionSave();
|
|
1521
|
+
var self = this;
|
|
1522
|
+
var url = "/admin/browser?filter=image&size_selector=true";
|
|
1523
|
+
var link = $("<a href='"+url+"'/>");
|
|
1524
|
+
var p = $("<p> </p>");
|
|
1525
|
+
AssetBrowser.showOverlay()
|
|
1526
|
+
$.get(url, null,
|
|
1527
|
+
function(markup) {
|
|
1528
|
+
AssetBrowser.load(p, link, markup, self );
|
|
1529
|
+
}
|
|
1530
|
+
);
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
RedactorPlugins.gluttonberg_embeds = {
|
|
1536
|
+
|
|
1537
|
+
init: function()
|
|
1538
|
+
{
|
|
1539
|
+
this.buttonAddAfter('table', 'gluttonberg_embeds', 'Embed', function()
|
|
1540
|
+
{
|
|
1541
|
+
this.selectionSave();
|
|
1542
|
+
console.log($(".redactor_btn_gluttonberg_embeds").attr('title'))
|
|
1543
|
+
var self = this;
|
|
1544
|
+
var url = "/admin/embeds/list-for-redactor";
|
|
1545
|
+
AssetBrowser.showOverlay()
|
|
1546
|
+
$.get(url, null,
|
|
1547
|
+
function(markup) {
|
|
1548
|
+
$("body").append(markup);
|
|
1549
|
+
$("#embedDialog .cancel").click(function(e){
|
|
1550
|
+
AssetBrowser.overlay.hide();
|
|
1551
|
+
$("#embedDialog").remove();
|
|
1552
|
+
e.preventDefault();
|
|
1553
|
+
});
|
|
1554
|
+
|
|
1555
|
+
$("#embedDialog .embed-btn").click(function(){
|
|
1556
|
+
self.selectionRestore();
|
|
1557
|
+
self.insertHtml($(this).attr('data-shortcode'));
|
|
1558
|
+
$("#embedDialog .cancel").click();
|
|
1559
|
+
e.preventDefault();
|
|
1560
|
+
})
|
|
1561
|
+
}
|
|
1562
|
+
);
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
RedactorPlugins.gluttonberg_pages = {
|
|
1568
|
+
|
|
1569
|
+
init: function()
|
|
1570
|
+
{
|
|
1571
|
+
var self = this;
|
|
1572
|
+
var dropdown = {};
|
|
1573
|
+
|
|
1574
|
+
if(linkCount > 0){
|
|
1575
|
+
dropdown["gluttonberg_pages"] = {
|
|
1576
|
+
title: 'Insert internal link',
|
|
1577
|
+
callback: function(){
|
|
1578
|
+
self.showModal(self);
|
|
1579
|
+
}
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
dropdown["link"] = {
|
|
1584
|
+
title: 'Insert link',
|
|
1585
|
+
func: 'linkShow'
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1588
|
+
dropdown["unlink"] = {
|
|
1589
|
+
title: 'Unlink',
|
|
1590
|
+
exec: 'unlink'
|
|
1591
|
+
};
|
|
1592
|
+
|
|
1593
|
+
dropdown["gluttonberg_files"] = {
|
|
1594
|
+
title: 'Attach file',
|
|
1595
|
+
callback: function(){
|
|
1596
|
+
this.selectionSave();
|
|
1597
|
+
self.showAssetSelector(self);
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
|
|
1601
|
+
this.buttonAddAfter('table', 'gb_link', 'Link', false, dropdown);
|
|
1602
|
+
},
|
|
1603
|
+
showAssetSelector : function(self){
|
|
1604
|
+
var url = "/admin/browser?size_selector=true";
|
|
1605
|
+
var link = $("<a href='"+url+"' class='attach'/>");
|
|
1606
|
+
var p = $("<p> </p>");
|
|
1607
|
+
$.get(url, null,
|
|
1608
|
+
function(markup) {
|
|
1609
|
+
AssetBrowser.load(p, link, markup, self );
|
|
1610
|
+
}
|
|
1611
|
+
);
|
|
1612
|
+
},
|
|
1613
|
+
showModal: function(self){
|
|
1614
|
+
self.selectionSave();
|
|
1615
|
+
$.get("/admin/pages_list_for_tinymce", null,
|
|
1616
|
+
function(response) {
|
|
1617
|
+
var options = "<option> </option> " + response;
|
|
1618
|
+
var modal_gluttonberg_link = String()
|
|
1619
|
+
+ '<section>'
|
|
1620
|
+
+ '<form id="redactorInsertLinkForm" method="post" action="">'
|
|
1621
|
+
+ '<div class="redactor_tab" id="redactor_tab1">'
|
|
1622
|
+
+ '<label>URL</label>'
|
|
1623
|
+
+ '<select id="redactor_gluttonberg_link_url" class="redactor_input chzn-select" data-placeholder="Please select a link" >'
|
|
1624
|
+
+ options
|
|
1625
|
+
+ '</select>'
|
|
1626
|
+
+ '<label>Text</label>'
|
|
1627
|
+
+ '<input type="text" class="redactor_input redactor_link_text" id="redactor_gluttonberg_link_url_text" />'
|
|
1628
|
+
+ '<label><input type="checkbox" id="redactor_gluttonberg_link_blank"> Open link in new tab</label>'
|
|
1629
|
+
+ '</div>'
|
|
1630
|
+
+ '</form>'
|
|
1631
|
+
+ '</section>'
|
|
1632
|
+
+ '<footer>'
|
|
1633
|
+
+ '<a href="#" class="redactor_modal_btn redactor_btn_modal_close">Cancel</a>'
|
|
1634
|
+
+ '<input type="button" class="redactor_modal_btn" id="redactor_insert_gluttonberg_link_btn" value="Insert" />'
|
|
1635
|
+
+ '</footer>';
|
|
1636
|
+
self.modalInit('Insert internal link', modal_gluttonberg_link, 460, function(){self.gluttonbergLinkModalClickcallback(self); });
|
|
1637
|
+
}
|
|
1638
|
+
);
|
|
1639
|
+
},
|
|
1640
|
+
gluttonbergLinkModalClickcallback : function(self)
|
|
1641
|
+
{
|
|
1642
|
+
self.insert_link_node = false;
|
|
1643
|
+
|
|
1644
|
+
var sel = self.getSelection();
|
|
1645
|
+
var url = '', text = '', target = '';
|
|
1646
|
+
|
|
1647
|
+
var elem = self.getParent();
|
|
1648
|
+
var par = $(elem).parent().get(0);
|
|
1649
|
+
if (par && par.tagName === 'A')
|
|
1650
|
+
{
|
|
1651
|
+
elem = par;
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
if (elem && elem.tagName === 'A')
|
|
1655
|
+
{
|
|
1656
|
+
url = elem.href;
|
|
1657
|
+
text = $(elem).text();
|
|
1658
|
+
target = elem.target;
|
|
1659
|
+
|
|
1660
|
+
self.insert_link_node = elem;
|
|
1661
|
+
}
|
|
1662
|
+
else{
|
|
1663
|
+
text = sel.toString();
|
|
1664
|
+
}
|
|
1665
|
+
$('#redactor_gluttonberg_link_url_text').val(text);
|
|
1666
|
+
$('#redactor_gluttonberg_link_url').val($('<a>').prop('href',url).prop('pathname'));
|
|
1667
|
+
if (target === '_blank'){
|
|
1668
|
+
$('#redactor_gluttonberg_link_blank').prop('checked', true);
|
|
1669
|
+
}
|
|
1670
|
+
$('#redactor_insert_gluttonberg_link_btn').click($.proxy(self.gbLinkProcess, self));
|
|
1671
|
+
setTimeout(function()
|
|
1672
|
+
{
|
|
1673
|
+
$('#redactor_gluttonberg_link_url').focus();
|
|
1674
|
+
}, 200);
|
|
1675
|
+
|
|
1676
|
+
$(".chzn-select").chosen();
|
|
1677
|
+
|
|
1678
|
+
},
|
|
1679
|
+
gbLinkProcess : function()
|
|
1680
|
+
{
|
|
1681
|
+
var self = this;
|
|
1682
|
+
var link = '', text = '', target = '', targetBlank = '';
|
|
1683
|
+
|
|
1684
|
+
// url
|
|
1685
|
+
link = $('#redactor_gluttonberg_link_url').val();
|
|
1686
|
+
text = $('#redactor_gluttonberg_link_url_text').val();
|
|
1687
|
+
|
|
1688
|
+
if ($('#redactor_gluttonberg_link_blank').prop('checked'))
|
|
1689
|
+
{
|
|
1690
|
+
target = ' target="_blank"';
|
|
1691
|
+
targetBlank = '_blank';
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
// test url (add protocol)
|
|
1695
|
+
var pattern = '((xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}';
|
|
1696
|
+
var re = new RegExp('^(http|ftp|https)://' + pattern, 'i');
|
|
1697
|
+
var re2 = new RegExp('^' + pattern, 'i');
|
|
1698
|
+
|
|
1699
|
+
if (link.search(re) == -1 && link.search(re2) == 0 && self.opts.linkProtocol)
|
|
1700
|
+
{
|
|
1701
|
+
link = self.opts.linkProtocol + link;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
self.gbLinkInsert('<a href="' + link + '"' + target + '>' + text + '</a>', $.trim(text), link, targetBlank);
|
|
1705
|
+
|
|
1706
|
+
},
|
|
1707
|
+
gbLinkInsert : function (a, text, link, target)
|
|
1708
|
+
{
|
|
1709
|
+
var self = this;
|
|
1710
|
+
self.selectionRestore();
|
|
1711
|
+
|
|
1712
|
+
if (text !== '')
|
|
1713
|
+
{
|
|
1714
|
+
if (self.insert_link_node)
|
|
1715
|
+
{
|
|
1716
|
+
self.bufferSet();
|
|
1717
|
+
$(self.insert_link_node).text(text).attr('href', link);
|
|
1718
|
+
|
|
1719
|
+
if (target !== '') $(self.insert_link_node).attr('target', target);
|
|
1720
|
+
else $(self.insert_link_node).removeAttr('target');
|
|
1721
|
+
|
|
1722
|
+
self.sync();
|
|
1723
|
+
}
|
|
1724
|
+
else
|
|
1725
|
+
{
|
|
1726
|
+
self.exec('inserthtml', a);
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
self.modalClose();
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
function getParameterByName(url, name ){
|
|
1734
|
+
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
|
1735
|
+
var regexS = "[\\?&]"+name+"=([^&#]*)",
|
|
1736
|
+
regex = new RegExp( regexS ),
|
|
1737
|
+
results = regex.exec( url );
|
|
1738
|
+
if( results == null ){
|
|
1739
|
+
return "";
|
|
1740
|
+
} else{
|
|
1741
|
+
return decodeURIComponent(results[1].replace(/\+/g, " "));
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
|
|
1746
|
+
/* Helper methods for form repeater. Add/remove functionality of repeatable component.
|
|
1747
|
+
*/
|
|
1748
|
+
var HtmlFormRepeater = {
|
|
1749
|
+
add: function(containerselector, rowSelector, link, callback){
|
|
1750
|
+
var duplicatedForm = $(containerselector).find(rowSelector).last().clone();
|
|
1751
|
+
HtmlFormRepeater.htmlCleanup(link, duplicatedForm);
|
|
1752
|
+
$(containerselector).append(duplicatedForm);
|
|
1753
|
+
var newElement = $(containerselector).find(rowSelector).last();
|
|
1754
|
+
if(callback != undefined){
|
|
1755
|
+
callback(newElement);
|
|
1756
|
+
}
|
|
1757
|
+
$(newElement).find("._destroy_button").click(function(e){
|
|
1758
|
+
HtmlFormRepeater.remove($(this).parents(rowSelector));
|
|
1759
|
+
e.preventDefault();
|
|
1760
|
+
});
|
|
1761
|
+
},
|
|
1762
|
+
htmlCleanup: function(link, duplicatedForm){
|
|
1763
|
+
var count = parseInt($(link).attr("data-count"));
|
|
1764
|
+
count++;
|
|
1765
|
+
|
|
1766
|
+
duplicatedForm.show();
|
|
1767
|
+
var html = duplicatedForm.html();
|
|
1768
|
+
if(html) {
|
|
1769
|
+
html = HtmlFormRepeater.idAndNameCleanup(count, html);
|
|
1770
|
+
duplicatedForm.html(html);
|
|
1771
|
+
HtmlFormRepeater.textInputCleanup(duplicatedForm);
|
|
1772
|
+
duplicatedForm.find("input._destroy").val("");
|
|
1773
|
+
}
|
|
1774
|
+
duplicatedForm.addClass("new-item");
|
|
1775
|
+
duplicatedForm.find("input._position").val(count);
|
|
1776
|
+
$(link).attr("data-count", count);
|
|
1777
|
+
},
|
|
1778
|
+
idAndNameCleanup: function(count, html){
|
|
1779
|
+
html = html.replace(/\[[0-9]+\]/g, "["+count+"]"); // name update
|
|
1780
|
+
html = html.replace(/_attributes_[0-9]+_/g, "_attributes_"+count+"_"); //id update
|
|
1781
|
+
return html;
|
|
1782
|
+
},
|
|
1783
|
+
textInputCleanup: function(duplicatedForm){
|
|
1784
|
+
duplicatedForm.find("input[type='text']").val("");
|
|
1785
|
+
},
|
|
1786
|
+
remove: function(rowSelector){
|
|
1787
|
+
$(rowSelector).hide();
|
|
1788
|
+
$(rowSelector).find("._destroy").val("true");
|
|
1789
|
+
},
|
|
1790
|
+
initRemoveButton: function(containerselector, rowSelector){
|
|
1791
|
+
$(containerselector).find("._destroy_button").click(function(e){
|
|
1792
|
+
HtmlFormRepeater.remove($(this).parents(rowSelector));
|
|
1793
|
+
e.preventDefault();
|
|
1794
|
+
});
|
|
1795
|
+
},
|
|
1796
|
+
initSorter: function(containerselector, rowSelector){
|
|
1797
|
+
$(containerselector).sortable({
|
|
1798
|
+
revert: true,
|
|
1799
|
+
handle: ".repeater-drag-node",
|
|
1800
|
+
update: function( event, ui ){
|
|
1801
|
+
$(containerselector).find(rowSelector).each(function(index){
|
|
1802
|
+
$(this).find("._position").val(index);
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
});
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
|