pageflow 17.0.5 → 17.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +342 -41
- data/README.md +3 -5
- data/admins/pageflow/accounts.rb +22 -20
- data/admins/pageflow/entry.rb +76 -26
- data/admins/pageflow/entry_templates.rb +10 -9
- data/admins/pageflow/folder.rb +1 -1
- data/admins/pageflow/membership.rb +15 -15
- data/admins/pageflow/revisions.rb +5 -5
- data/admins/pageflow/site_root_entry.rb +64 -0
- data/admins/pageflow/sites.rb +12 -3
- data/admins/pageflow/translations.rb +75 -0
- data/admins/pageflow/user.rb +21 -35
- data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
- data/app/assets/javascripts/pageflow/admin/entries.js +30 -5
- data/app/assets/javascripts/pageflow/dist/ui.js +4228 -900
- data/app/assets/javascripts/pageflow/editor/vendor.js +0 -1
- data/app/assets/javascripts/pageflow/ui.js +0 -1
- data/app/assets/stylesheets/pageflow/admin/entries/index_table.scss +2 -1
- data/app/assets/stylesheets/pageflow/admin/entry_comments_indicator.scss +45 -0
- data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -0
- data/app/assets/stylesheets/pageflow/admin.scss +1 -0
- data/app/assets/stylesheets/pageflow/animations/spin.scss +9 -0
- data/app/assets/stylesheets/pageflow/animations.scss +1 -0
- data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +27 -5
- data/app/assets/stylesheets/pageflow/editor/base.scss +11 -1
- data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +20 -2
- data/app/assets/stylesheets/pageflow/editor/edit_configuration_view.scss +5 -0
- data/app/assets/stylesheets/pageflow/editor/file_folders.scss +127 -0
- data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +5 -2
- data/app/assets/stylesheets/pageflow/editor/file_meta_data_overlay.scss +45 -0
- data/app/assets/stylesheets/pageflow/editor/file_preview.scss +138 -0
- data/app/assets/stylesheets/pageflow/editor/file_references.scss +68 -0
- data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +1 -1
- data/app/assets/stylesheets/pageflow/editor/file_stage_icons.scss +17 -0
- data/app/assets/stylesheets/pageflow/editor/file_stages.scss +25 -32
- data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +31 -48
- data/app/assets/stylesheets/pageflow/editor/file_type_pills.scss +73 -0
- data/app/assets/stylesheets/pageflow/editor/files.scss +242 -50
- data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +161 -9
- data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
- data/app/assets/stylesheets/pageflow/editor/info_box.scss +23 -3
- data/app/assets/stylesheets/pageflow/editor/inputs/edit_defaults_button.scss +15 -0
- data/app/assets/stylesheets/pageflow/editor/inputs.scss +1 -0
- data/app/assets/stylesheets/pageflow/editor/list.scss +89 -37
- data/app/assets/stylesheets/pageflow/editor/list_search_field.scss +52 -0
- data/app/assets/stylesheets/pageflow/editor/manage_files.scss +9 -0
- data/app/assets/stylesheets/pageflow/editor/menu.scss +14 -0
- data/app/assets/stylesheets/pageflow/editor/move_to_folder_dialog.scss +83 -0
- data/app/assets/stylesheets/pageflow/editor/outline.scss +0 -13
- data/app/assets/stylesheets/pageflow/editor/sortable.scss +12 -0
- data/app/assets/stylesheets/pageflow/mixins/buttons.scss +4 -4
- data/app/assets/stylesheets/pageflow/mixins/pageflow.scss +9 -5
- data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
- data/app/assets/stylesheets/pageflow/ui/forms.scss +38 -4
- data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
- data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -8
- data/app/assets/stylesheets/pageflow/ui/input/file_name_input.scss +37 -0
- data/app/assets/stylesheets/pageflow/ui/input/text_area_input.scss +15 -0
- data/app/assets/stylesheets/pageflow/ui/overrides.scss +8 -0
- data/app/assets/stylesheets/pageflow/ui/properties.scss +34 -0
- data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
- data/app/assets/stylesheets/pageflow/ui.scss +4 -1
- data/app/controllers/concerns/pageflow/controller_delegation.rb +1 -1
- data/app/controllers/concerns/pageflow/edit_locking.rb +17 -10
- data/app/controllers/concerns/pageflow/entry_password_protection.rb +1 -0
- data/app/controllers/concerns/pageflow/public_https_mode.rb +2 -1
- data/app/controllers/concerns/pageflow/quota_verification.rb +5 -4
- data/app/controllers/pageflow/admin/initial_passwords_controller.rb +1 -0
- data/app/controllers/pageflow/application_controller.rb +19 -19
- data/app/controllers/pageflow/chapters_controller.rb +3 -2
- data/app/controllers/pageflow/edit_locks_controller.rb +3 -2
- data/app/controllers/pageflow/editor/encoding_confirmations_controller.rb +1 -0
- data/app/controllers/pageflow/editor/entries_controller.rb +3 -1
- data/app/controllers/pageflow/editor/entry_publications_controller.rb +1 -0
- data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
- data/app/controllers/pageflow/editor/file_import_controller.rb +4 -3
- data/app/controllers/pageflow/editor/files_controller.rb +20 -10
- data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
- data/app/controllers/pageflow/editor/widgets_controller.rb +1 -0
- data/app/controllers/pageflow/entries_controller.rb +85 -21
- data/app/controllers/pageflow/feeds_controller.rb +1 -1
- data/app/controllers/pageflow/files_controller.rb +1 -0
- data/app/controllers/pageflow/pages_controller.rb +4 -2
- data/app/controllers/pageflow/review/comment_thread_reads_controller.rb +30 -0
- data/app/controllers/pageflow/review/comment_threads_controller.rb +60 -0
- data/app/controllers/pageflow/review/comments_controller.rb +53 -0
- data/app/controllers/pageflow/revisions_controller.rb +5 -1
- data/app/controllers/pageflow/sitemaps_controller.rb +1 -1
- data/app/controllers/pageflow/storylines_controller.rb +1 -0
- data/app/helpers/pageflow/admin/cutoff_modes_helper.rb +12 -0
- data/app/helpers/pageflow/admin/entries_helper.rb +41 -1
- data/app/helpers/pageflow/admin/entry_translations_helper.rb +18 -0
- data/app/helpers/pageflow/admin/features_helper.rb +1 -1
- data/app/helpers/pageflow/admin/form_helper.rb +3 -3
- data/app/helpers/pageflow/admin/locales_helper.rb +10 -2
- data/app/helpers/pageflow/admin/memberships_helper.rb +32 -32
- data/app/helpers/pageflow/admin/revisions_helper.rb +1 -1
- data/app/helpers/pageflow/admin/sites_helper.rb +22 -0
- data/app/helpers/pageflow/admin/users_helper.rb +7 -5
- data/app/helpers/pageflow/admin/widgets_helper.rb +5 -5
- data/app/helpers/pageflow/asset_urls_helper.rb +1 -1
- data/app/helpers/pageflow/audio_files_helper.rb +5 -2
- data/app/helpers/pageflow/background_image_helper.rb +7 -6
- data/app/helpers/pageflow/common_entry_seed_helper.rb +7 -7
- data/app/helpers/pageflow/editor/config_helper.rb +3 -1
- data/app/helpers/pageflow/editor/files_helper.rb +1 -1
- data/app/helpers/pageflow/embed_code_helper.rb +3 -3
- data/app/helpers/pageflow/entries_helper.rb +52 -46
- data/app/helpers/pageflow/entry_json_seed_helper.rb +7 -6
- data/app/helpers/pageflow/feeds_helper.rb +2 -2
- data/app/helpers/pageflow/file_background_images_helper.rb +2 -2
- data/app/helpers/pageflow/file_thumbnails_helper.rb +4 -3
- data/app/helpers/pageflow/files_helper.rb +5 -4
- data/app/helpers/pageflow/folders_helper.rb +8 -5
- data/app/helpers/pageflow/help_entries_helper.rb +2 -2
- data/app/helpers/pageflow/hreflang_links_helper.rb +37 -0
- data/app/helpers/pageflow/info_box_helper.rb +7 -11
- data/app/helpers/pageflow/media_query_helper.rb +3 -3
- data/app/helpers/pageflow/navigation_bar_helper.rb +1 -1
- data/app/helpers/pageflow/overview_helper.rb +1 -1
- data/app/helpers/pageflow/page_types_helper.rb +5 -5
- data/app/helpers/pageflow/pages_helper.rb +29 -15
- data/app/helpers/pageflow/public_i18n_helper.rb +10 -9
- data/app/helpers/pageflow/quota_helper.rb +4 -4
- data/app/helpers/pageflow/render_json_helper.rb +6 -3
- data/app/helpers/pageflow/revision_file_helper.rb +2 -1
- data/app/helpers/pageflow/sites_helper.rb +3 -3
- data/app/helpers/pageflow/social_share_helper.rb +24 -10
- data/app/helpers/pageflow/social_share_links_helper.rb +12 -9
- data/app/helpers/pageflow/structured_data_helper.rb +5 -2
- data/app/helpers/pageflow/stub_page_configuration.rb +7 -3
- data/app/helpers/pageflow/text_direction_helper.rb +1 -1
- data/app/helpers/pageflow/themes_helper.rb +2 -4
- data/app/helpers/pageflow/video_files_helper.rb +29 -13
- data/app/helpers/pageflow/widgets_helper.rb +8 -6
- data/app/inputs/pageflow_permalink_input.rb +8 -3
- data/app/jobs/pageflow/application_job.rb +1 -0
- data/app/jobs/pageflow/entry_export_import/upload_and_publish_file_job.rb +1 -1
- data/app/jobs/pageflow/poll_meta_data_from_zencoder_job.rb +1 -0
- data/app/jobs/pageflow/poll_zencoder_job.rb +3 -2
- data/app/jobs/pageflow/process_image_or_text_track_job.rb +1 -0
- data/app/jobs/pageflow/prune_auto_snapshots_job.rb +1 -0
- data/app/jobs/pageflow/request_meta_data_from_zencoder_job.rb +1 -0
- data/app/jobs/pageflow/submit_file_to_zencoder_job.rb +1 -0
- data/app/mailers/pageflow/user_mailer.rb +1 -0
- data/app/models/concerns/pageflow/auto_generated_perma_id.rb +20 -1
- data/app/models/concerns/pageflow/entry_publication_states.rb +7 -3
- data/app/models/concerns/pageflow/feature_target.rb +8 -4
- data/app/models/concerns/pageflow/output_source.rb +3 -3
- data/app/models/concerns/pageflow/permalinkable.rb +2 -1
- data/app/models/concerns/pageflow/reusable_file.rb +24 -24
- data/app/models/concerns/pageflow/serialization_blacklist.rb +3 -5
- data/app/models/concerns/pageflow/suspendable.rb +5 -3
- data/app/models/concerns/pageflow/theme_referencer.rb +1 -1
- data/app/models/concerns/pageflow/translatable.rb +62 -0
- data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
- data/app/models/concerns/pageflow/uploadable_file.rb +6 -6
- data/app/models/pageflow/account.rb +6 -5
- data/app/models/pageflow/account_member_query.rb +1 -1
- data/app/models/pageflow/account_role_query.rb +1 -1
- data/app/models/pageflow/application_query.rb +1 -1
- data/app/models/pageflow/application_record.rb +1 -1
- data/app/models/pageflow/audio_file.rb +4 -4
- data/app/models/pageflow/audio_file_url_templates.rb +1 -1
- data/app/models/pageflow/authentication_token.rb +2 -2
- data/app/models/pageflow/chapter.rb +6 -1
- data/app/models/pageflow/chapter_scaffold.rb +2 -4
- data/app/models/pageflow/cname_site_request_scope.rb +1 -1
- data/app/models/pageflow/comment.rb +30 -0
- data/app/models/pageflow/comment_thread.rb +65 -0
- data/app/models/pageflow/comment_thread_read.rb +22 -0
- data/app/models/pageflow/customized_theme.rb +9 -8
- data/app/models/pageflow/draft_entry.rb +49 -9
- data/app/models/pageflow/edit_lock.rb +19 -21
- data/app/models/pageflow/encoding_confirmation.rb +2 -2
- data/app/models/pageflow/entries_feed.rb +2 -2
- data/app/models/pageflow/entry.rb +46 -30
- data/app/models/pageflow/entry_at_revision.rb +14 -2
- data/app/models/pageflow/entry_comment_summary.rb +114 -0
- data/app/models/pageflow/entry_duplicate.rb +8 -5
- data/app/models/pageflow/entry_publication.rb +2 -2
- data/app/models/pageflow/entry_role_query.rb +4 -4
- data/app/models/pageflow/entry_template.rb +4 -4
- data/app/models/pageflow/entry_title_or_account_name_query.rb +2 -2
- data/app/models/pageflow/entry_translation_group.rb +42 -0
- data/app/models/pageflow/file_folder.rb +74 -0
- data/app/models/pageflow/file_reuse.rb +5 -4
- data/app/models/pageflow/file_usage.rb +18 -3
- data/app/models/pageflow/folder.rb +2 -2
- data/app/models/pageflow/home_button.rb +7 -7
- data/app/models/pageflow/image_file.rb +44 -25
- data/app/models/pageflow/image_file_url_templates.rb +4 -4
- data/app/models/pageflow/invitation_form.rb +2 -1
- data/app/models/pageflow/legal_info.rb +38 -0
- data/app/models/pageflow/managed_user_query.rb +1 -1
- data/app/models/pageflow/membership.rb +5 -5
- data/app/models/pageflow/nested_revision_component_copy.rb +263 -0
- data/app/models/pageflow/null_user.rb +1 -1
- data/app/models/pageflow/overview_button.rb +1 -1
- data/app/models/pageflow/page.rb +7 -3
- data/app/models/pageflow/permalink.rb +24 -2
- data/app/models/pageflow/permalink_directory.rb +7 -0
- data/app/models/pageflow/permalink_redirect.rb +7 -0
- data/app/models/pageflow/positioned_file.rb +5 -5
- data/app/models/pageflow/potential_entry_translations.rb +55 -0
- data/app/models/pageflow/potential_memberships.rb +5 -4
- data/app/models/pageflow/published_entry.rb +62 -11
- data/app/models/pageflow/revision.rb +29 -16
- data/app/models/pageflow/roles.rb +14 -18
- data/app/models/pageflow/site.rb +46 -3
- data/app/models/pageflow/site_root_entry_form.rb +27 -0
- data/app/models/pageflow/sitemaps.rb +10 -1
- data/app/models/pageflow/storyline.rb +5 -2
- data/app/models/pageflow/storyline_scaffold.rb +1 -1
- data/app/models/pageflow/text_track_file.rb +1 -1
- data/app/models/pageflow/text_track_file_url_templates.rb +1 -1
- data/app/models/pageflow/theme_customization_file.rb +3 -2
- data/app/models/pageflow/thumbnail_file_resolver.rb +1 -1
- data/app/models/pageflow/url_template.rb +1 -1
- data/app/models/pageflow/used_file.rb +13 -3
- data/app/models/pageflow/user_name_query.rb +2 -2
- data/app/models/pageflow/video_file.rb +22 -15
- data/app/models/pageflow/video_file_url_templates.rb +6 -4
- data/app/models/pageflow/widget.rb +5 -4
- data/app/models/pageflow/with_file_usage_extension.rb +1 -1
- data/app/models/pageflow/zencoder_attachment.rb +8 -8
- data/app/policies/pageflow/account_policy.rb +3 -1
- data/app/policies/pageflow/admin/admin_only_tab_policy.rb +1 -0
- data/app/policies/pageflow/admin/entry_tab_policy.rb +1 -0
- data/app/policies/pageflow/application_policy.rb +2 -0
- data/app/policies/pageflow/entry_policy.rb +7 -1
- data/app/policies/pageflow/entry_template_policy.rb +2 -1
- data/app/policies/pageflow/file_policy.rb +4 -7
- data/app/policies/pageflow/folder_policy.rb +18 -8
- data/app/policies/pageflow/membership_policy.rb +6 -4
- data/app/policies/pageflow/site_policy.rb +10 -3
- data/app/policies/pageflow/user_policy.rb +6 -4
- data/app/state_machines/pageflow/image_and_text_track_processing_state_machine.rb +3 -2
- data/app/state_machines/pageflow/media_encoding_state_machine.rb +5 -4
- data/app/views/admin/accounts/_entry_template_details.html.arb +2 -2
- data/app/views/admin/entries/_attributes_table.html.arb +6 -5
- data/app/views/admin/entries/_form.html.erb +2 -1
- data/app/views/admin/entries/_permalink_inputs.html.erb +9 -2
- data/app/views/admin/entry_templates/_form.html.erb +1 -3
- data/app/views/admin/site_root_entry/choose.html.erb +19 -0
- data/app/views/admin/sites/_fields.html.erb +14 -1
- data/app/views/admin/translations/_form.html.erb +31 -0
- data/app/views/admin/users/_attributes_table.html.arb +13 -0
- data/app/views/components/pageflow/admin/add_membership_button.rb +13 -12
- data/app/views/components/pageflow/admin/custom_scopes_renderer.rb +1 -0
- data/app/views/components/pageflow/admin/embed_code_field.rb +1 -0
- data/app/views/components/pageflow/admin/embedded_index_table.rb +9 -10
- data/app/views/components/pageflow/admin/entries_tab.rb +1 -0
- data/app/views/components/pageflow/admin/entry_publication_state_indicator.rb +6 -5
- data/app/views/components/pageflow/admin/entry_templates_tab.rb +2 -1
- data/app/views/components/pageflow/admin/entry_translations_tab.rb +102 -0
- data/app/views/components/pageflow/admin/entry_user_badge_list.rb +1 -0
- data/app/views/components/pageflow/admin/extensible_attributes_table.rb +9 -8
- data/app/views/components/pageflow/admin/features_tab.rb +1 -0
- data/app/views/components/pageflow/admin/grouped_folder_list.rb +1 -0
- data/app/views/components/pageflow/admin/icon_link_to.rb +1 -0
- data/app/views/components/pageflow/admin/members_tab.rb +4 -3
- data/app/views/components/pageflow/admin/membership_role_with_tooltip.rb +3 -2
- data/app/views/components/pageflow/admin/revisions_tab.rb +14 -10
- data/app/views/components/pageflow/admin/sites_tab.rb +1 -0
- data/app/views/components/pageflow/admin/tabs_view.rb +1 -0
- data/app/views/components/pageflow/admin/timestamp.rb +6 -5
- data/app/views/components/pageflow/admin/user_account_badge_list.rb +2 -3
- data/app/views/components/pageflow/admin/user_accounts_tab.rb +1 -0
- data/app/views/components/pageflow/admin/user_entries_tab.rb +1 -0
- data/app/views/components/pageflow/admin/users_tab.rb +1 -0
- data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
- data/app/views/pageflow/editor/config/_seeds.json.jbuilder +5 -3
- data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
- data/app/views/pageflow/editor/entries/index.json.jbuilder +1 -1
- data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
- data/app/views/pageflow/editor/entries/show.json.jbuilder +1 -1
- data/app/views/pageflow/editor/entry_publications/check.json.jbuilder +2 -2
- data/app/views/pageflow/editor/file_folders/_file_folder.json.jbuilder +5 -0
- data/app/views/pageflow/editor/file_folders/create.json.jbuilder +1 -0
- data/app/views/pageflow/editor/file_folders/index.json.jbuilder +3 -0
- data/app/views/pageflow/editor/files/_file.json.jbuilder +7 -14
- data/app/views/pageflow/editor/files/create.json.jbuilder +1 -1
- data/app/views/pageflow/editor/files/index.json.jbuilder +1 -1
- data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
- data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
- data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +4 -3
- data/app/views/pageflow/entries/share_menu/_bluesky_link.html.erb +8 -0
- data/app/views/pageflow/entries/share_menu/_threads_link.html.erb +8 -0
- data/app/views/pageflow/files/_file.json.jbuilder +5 -3
- data/app/views/pageflow/image_files/_image_file.json.jbuilder +0 -1
- data/app/views/pageflow/review/comment_threads/_comment_thread.json.jbuilder +20 -0
- data/app/views/pageflow/review/comment_threads/create.json.jbuilder +2 -0
- data/app/views/pageflow/review/comment_threads/index.json.jbuilder +13 -0
- data/app/views/pageflow/review/comments/_comment.json.jbuilder +13 -0
- data/app/views/pageflow/review/comments/create.json.jbuilder +1 -0
- data/app/views/pageflow/sitemaps/index.xml.builder +9 -1
- data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
- data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
- data/app/views/pageflow/structured_data/_entry.json.jbuilder +2 -3
- data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
- data/config/initializers/active_admin_patches.rb +3 -6
- data/config/initializers/admin_resource_tabs.rb +3 -0
- data/config/initializers/paperclip.rb +1 -0
- data/config/initializers/symmetric_encryption.rb +1 -1
- data/config/initializers/zencoder.rb +24 -13
- data/config/locales/de.yml +256 -12
- data/config/locales/en.yml +253 -15
- data/config/routes.rb +29 -13
- data/config/spring.rb +2 -1
- data/db/migrate/20140418225525_setup_schema.rb +2 -2
- data/db/migrate/20190306161431_copy_file_attributes_of_failed_uploads.rb +2 -2
- data/db/migrate/20190820152900_drop_accounts_themes.rb +2 -1
- data/db/migrate/20191202145757_create_pageflow_scrolled_sections.rb +11 -11
- data/db/migrate/20191202150657_create_pageflow_scrolled_chapters.rb +1 -1
- data/db/migrate/20191202154723_create_pageflow_scrolled_content_elements.rb +9 -9
- data/db/migrate/20191219143450_add_position_to_content_elements.rb +2 -1
- data/db/migrate/20200117133200_change_revision_appearance_option_default_and_null.rb +2 -1
- data/db/migrate/20200122115400_create_pageflow_entry_templates.rb +25 -25
- data/db/migrate/20200206134400_convert_legacy_scrolled_content_element_types.rb +3 -3
- data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +2 -2
- data/db/migrate/20230120092923_create_other_files.rb +2 -1
- data/db/migrate/20230419083307_create_pageflow_entry_translation_group.rb +9 -0
- data/db/migrate/20240612110434_add_cutoff_mode_name_to_sites.rb +5 -0
- data/db/migrate/20240918084059_create_pageflow_permalink_redirects.rb +14 -0
- data/db/migrate/20250508172234_ensure_scrolled_entries_have_main_storyline.rb +14 -0
- data/db/migrate/20250617090048_add_custom404_entry_to_sites.rb +5 -0
- data/db/migrate/20250617100000_add_perma_id_counter_to_entries.rb +28 -0
- data/db/migrate/20250722174123_add_perma_id_to_chapters.rb +10 -0
- data/db/migrate/20250725080603_add_perma_id_indexes_to_revision_components.rb +13 -0
- data/db/migrate/20250726000000_add_display_name_to_file_usages.rb +5 -0
- data/db/migrate/20251015000000_add_structured_data_type_name_to_revisions.rb +5 -0
- data/db/migrate/20251029142849_convert_legacy_social_embeds_to_unified_social_embed.rb +38 -0
- data/db/migrate/20251119083347_fix_main_storyline_positions.rb +16 -0
- data/db/migrate/20251119083348_ensure_scrolled_entries_have_excursion_storyline.rb +15 -0
- data/db/migrate/20260303000000_add_layout_version_to_revisions.rb +6 -0
- data/db/migrate/20260323000000_create_comment_threads_and_comments.rb +30 -0
- data/db/migrate/20260414000000_add_subject_range_to_comment_threads.rb +5 -0
- data/db/migrate/20260415000000_add_section_perma_id_to_comment_threads.rb +5 -0
- data/db/migrate/20260727000000_add_quote_to_comments.rb +5 -0
- data/db/migrate/20260728000000_create_file_folders.rb +17 -0
- data/db/migrate/20260805000000_add_attribute_translations_to_sites.rb +5 -0
- data/db/migrate/20260806000000_add_edited_at_to_comments.rb +5 -0
- data/db/migrate/20260810000000_create_pageflow_scrolled_lottie_files.rb +24 -0
- data/db/migrate/20260817000000_create_comment_thread_reads.rb +16 -0
- data/db/migrate/20260819000000_add_unread_comments_since_at_to_users.rb +18 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +12599 -5398
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +1275 -4560
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20204 -22
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18657 -19
- data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +1 -0
- data/entry_types/paged/app/helpers/pageflow_paged/page_background_asset_helper.rb +1 -1
- data/entry_types/paged/app/helpers/pageflow_paged/third_party_embed_consent_helper.rb +7 -7
- data/entry_types/paged/app/views/pageflow_paged/editor/entries/_seed.json.jbuilder +1 -0
- data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
- data/entry_types/paged/lib/pageflow_paged/plugin.rb +4 -0
- data/entry_types/paged/lib/pageflow_paged/react/page_type.rb +1 -1
- data/entry_types/paged/lib/pageflow_paged/react/widget_type.rb +3 -3
- data/entry_types/paged/lib/pageflow_paged.rb +1 -1
- data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +5 -3
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +35 -5
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +4 -5
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +23 -2
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +3 -3
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +8 -5
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +7 -3
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +72 -10
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +41 -12
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +23 -25
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +189 -3
- data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +15 -14
- data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +61 -7
- data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file.rb +6 -0
- data/entry_types/scrolled/app/models/pageflow_scrolled/lottie_file_url_templates.rb +16 -0
- data/entry_types/scrolled/app/models/pageflow_scrolled/section.rb +12 -1
- data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +20 -1
- data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +2 -2
- data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +15 -12
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +45 -17
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry_translations.json.jbuilder +14 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +34 -5
- data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
- data/entry_types/scrolled/app/views/pageflow_scrolled/storylines/_storyline.json.jbuilder +7 -0
- data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
- data/entry_types/scrolled/config/locales/de.yml +1094 -78
- data/entry_types/scrolled/config/locales/en.yml +1083 -78
- data/entry_types/scrolled/config/routes.rb +18 -8
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +11 -11
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantDesktop.svg +56 -0
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantMobile.svg +22 -0
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/themes_plugin.rb.tt +26 -11
- data/entry_types/scrolled/lib/pageflow_scrolled/additional_packs.rb +27 -8
- data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
- data/entry_types/scrolled/lib/pageflow_scrolled/additional_theme_assets.rb +27 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +67 -10
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +1 -1
- data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +2 -1
- data/entry_types/scrolled/lib/pageflow_scrolled/entry_file_reference_locations.rb +71 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/entry_structured_data_types/faq_page.rb +58 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/file_reference_locations.rb +69 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +222 -19
- data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
- data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +76 -54
- data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
- data/entry_types/scrolled/lib/pageflow_scrolled.rb +14 -1
- data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +24 -5
- data/entry_types/scrolled/package/config/configurationSchemas.js +70 -0
- data/entry_types/scrolled/package/config/rollup/configurationSchemas.js +19 -0
- data/entry_types/scrolled/package/config/webpack.js +94 -0
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1795 -0
- data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/inlineBeforeAfter-frontend.js +219 -0
- data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/lottieAnimation-frontend.js +244 -0
- data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/socialEmbed-frontend.js +823 -0
- data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +109 -0
- data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/twitterEmbed-frontend.js +277 -0
- data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements/videoEmbed-frontend.js +244 -0
- data/entry_types/scrolled/package/contentElements-editor.js +3155 -583
- data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
- data/entry_types/scrolled/package/contentElements-frontend.js +3375 -1585
- data/entry_types/scrolled/package/editor.css +1 -0
- data/entry_types/scrolled/package/editor.js +8452 -2867
- data/entry_types/scrolled/package/entryState.js +1600 -0
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-20c600de.js +1979 -0
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-58189220.js +2538 -0
- data/entry_types/scrolled/package/frontend/{PhonePlatformContext-4ec6b2de.js → PhonePlatformContext-035a99fa.js} +9 -15
- data/entry_types/scrolled/package/frontend/PhonePlatformContext-9da43797.js +33 -0
- data/entry_types/scrolled/package/frontend/Placeholder.module-bf0966b4.js +5267 -0
- data/entry_types/scrolled/package/frontend/Placeholder.module-d22a9335.js +4180 -0
- data/entry_types/scrolled/package/frontend/ThemeIcon-ab834849.js +754 -0
- data/entry_types/scrolled/package/frontend/ThemeIcon-f6cb3a8f.js +773 -0
- data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-30fd1124.js +39 -0
- data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-61c25224.js +72 -0
- data/entry_types/scrolled/package/frontend/Viewer-1074fd59.js +147 -0
- data/entry_types/scrolled/package/frontend/Viewer-1482ca34.js +480 -0
- data/entry_types/scrolled/package/frontend/Viewer-70504231.js +210 -0
- data/entry_types/scrolled/package/frontend/{Viewer-1bb5597c.js → Viewer-cc8d4072.js} +100 -135
- data/entry_types/scrolled/package/frontend/Wavesurfer-656e3c36.js +302 -0
- data/entry_types/scrolled/package/frontend/Wavesurfer-b753b838.js +385 -0
- data/entry_types/scrolled/package/frontend/commenting.css +1 -0
- data/entry_types/scrolled/package/frontend/extensions-167ae143.js +1455 -0
- data/entry_types/scrolled/package/frontend/extensions-2318f92b.js +5918 -0
- data/entry_types/scrolled/package/frontend/extensions-a461fd13.js +4890 -0
- data/entry_types/scrolled/package/frontend/extensions-c98269fd.js +1982 -0
- data/entry_types/scrolled/package/frontend/i18n-493cd2a6.js +93 -0
- data/entry_types/scrolled/package/frontend/i18n-e06cac14.js +100 -0
- data/entry_types/scrolled/package/frontend/{index-11f32f10.js → index-2e5546f7.js} +39 -54
- data/entry_types/scrolled/package/frontend/index-de2b418d.js +130 -0
- data/entry_types/scrolled/package/frontend/index.css +1 -1
- data/entry_types/scrolled/package/frontend/index.js +1976 -1367
- data/entry_types/scrolled/package/frontend/inlineEditing.css +1 -0
- data/entry_types/scrolled/package/frontend/useContentElementEditorState-a084912e.js +25 -0
- data/entry_types/scrolled/package/frontend/useDelayedBoolean-a387d85b.js +24 -0
- data/entry_types/scrolled/package/frontend/usePhonePlatform-4ecb96d4.js +8 -0
- data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
- data/entry_types/scrolled/package/frontend-server.js +20 -210
- data/entry_types/scrolled/package/package.json +22 -12
- data/entry_types/scrolled/package/review.css +1 -0
- data/entry_types/scrolled/package/review.js +3306 -0
- data/entry_types/scrolled/package/testHelpers.js +952 -239
- data/entry_types/scrolled/package/values/widgets.module.css +18 -0
- data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
- data/entry_types/scrolled/package/widgets/consentBar.js +275 -315
- data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
- data/entry_types/scrolled/package/widgets/defaultNavigation.js +961 -432
- data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -0
- data/entry_types/scrolled/package/widgets/excursionSheet.js +225 -0
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -32
- data/entry_types/scrolled/package/widgets/iconScrollIndicator.css +1 -0
- data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +67 -0
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -0
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +100 -0
- data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/textInlineFileRights.js +48 -26
- data/entry_types/scrolled/package/widgets-server.js +2 -0
- data/entry_types/scrolled/spec/factories/chapters.rb +14 -1
- data/entry_types/scrolled/spec/factories/content_elements.rb +1 -1
- data/entry_types/scrolled/spec/factories/lottie_files.rb +29 -0
- data/entry_types/scrolled/spec/fixtures/animation.lottie +0 -0
- data/entry_types/scrolled/spec/fixtures/font.woff +0 -0
- data/entry_types/scrolled/spec/fixtures/font.woff2 +0 -0
- data/lib/generators/pageflow/active_admin_initializer/active_admin_initializer_generator.rb +5 -3
- data/lib/generators/pageflow/assets/assets_generator.rb +7 -5
- data/lib/generators/pageflow/cancan/cancan_generator.rb +2 -1
- data/lib/generators/pageflow/cancan/templates/ability.rb +1 -1
- data/lib/generators/pageflow/error_pages/error_pages_generator.rb +2 -1
- data/lib/generators/pageflow/initializer/initializer_generator.rb +3 -2
- data/lib/generators/pageflow/install/install_generator.rb +2 -2
- data/lib/generators/pageflow/procfile/procfile_generator.rb +2 -1
- data/lib/generators/pageflow/resque/resque_generator.rb +4 -4
- data/lib/generators/pageflow/resque/templates/resque.rake +1 -1
- data/lib/generators/pageflow/routes/routes_generator.rb +4 -2
- data/lib/generators/pageflow/seeds/seeds_generator.rb +3 -2
- data/lib/generators/pageflow/seeds/templates/seeds.rb +6 -6
- data/lib/generators/pageflow/theme/theme_generator.rb +2 -1
- data/lib/generators/pageflow/user/user_generator.rb +2 -1
- data/lib/pageflow/ability_mixin.rb +25 -15
- data/lib/pageflow/active_admin_patches/views/attributes_table.rb +1 -0
- data/lib/pageflow/active_admin_patches/views/pages/base.rb +3 -2
- data/lib/pageflow/active_admin_patches/views/table_for.rb +1 -0
- data/lib/pageflow/additional_headers.rb +27 -0
- data/lib/pageflow/admin/attributes_table_rows.rb +3 -3
- data/lib/pageflow/admin/tabs.rb +1 -1
- data/lib/pageflow/built_in_file_type.rb +1 -1
- data/lib/pageflow/built_in_page_types_plugin.rb +1 -1
- data/lib/pageflow/built_in_widget_type.rb +2 -2
- data/lib/pageflow/built_in_widget_types_plugin.rb +2 -1
- data/lib/pageflow/configuration.rb +183 -18
- data/lib/pageflow/cutoff_modes.rb +39 -0
- data/lib/pageflow/deprecation.rb +19 -0
- data/lib/pageflow/editor_controller.rb +6 -10
- data/lib/pageflow/engine.rb +5 -6
- data/lib/pageflow/entries_controller_env_helper.rb +32 -2
- data/lib/pageflow/entry_export_import/attachment_files.rb +1 -1
- data/lib/pageflow/entry_export_import/entry_serialization.rb +9 -8
- data/lib/pageflow/entry_export_import/file_mappings.rb +1 -0
- data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
- data/lib/pageflow/entry_export_import/revision_serialization/import.rb +11 -1
- data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
- data/lib/pageflow/entry_export_import.rb +3 -3
- data/lib/pageflow/entry_structured_data_types.rb +43 -0
- data/lib/pageflow/entry_type_configuration.rb +1 -0
- data/lib/pageflow/entry_types.rb +2 -2
- data/lib/pageflow/feature.rb +1 -1
- data/lib/pageflow/features.rb +4 -6
- data/lib/pageflow/file_importers.rb +4 -4
- data/lib/pageflow/file_type.rb +5 -5
- data/lib/pageflow/file_types.rb +4 -4
- data/lib/pageflow/global_config_api.rb +5 -6
- data/lib/pageflow/help_entries.rb +7 -7
- data/lib/pageflow/help_entry.rb +1 -1
- data/lib/pageflow/hooks.rb +1 -1
- data/lib/pageflow/nested_revision_component.rb +9 -27
- data/lib/pageflow/news_item_api.rb +1 -1
- data/lib/pageflow/oembed_providers.rb +42 -0
- data/lib/pageflow/page_type.rb +2 -3
- data/lib/pageflow/page_types.rb +3 -3
- data/lib/pageflow/paperclip_interpolations/support.rb +1 -1
- data/lib/pageflow/paperclip_processors/vtt.rb +1 -0
- data/lib/pageflow/paperclip_processors/webp.rb +2 -2
- data/lib/pageflow/partial_editor_fragment_renderer.rb +2 -2
- data/lib/pageflow/plugin.rb +1 -2
- data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
- data/lib/pageflow/quota.rb +9 -5
- data/lib/pageflow/quotas.rb +1 -1
- data/lib/pageflow/rails_version.rb +14 -2
- data/lib/pageflow/react.rb +1 -1
- data/lib/pageflow/revision_component.rb +8 -40
- data/lib/pageflow/revision_components.rb +16 -6
- data/lib/pageflow/seeds.rb +12 -16
- data/lib/pageflow/theme.rb +1 -1
- data/lib/pageflow/theme_customizations.rb +10 -10
- data/lib/pageflow/themes.rb +44 -3
- data/lib/pageflow/user_mixin.rb +18 -6
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow/widget_type.rb +4 -4
- data/lib/pageflow/widget_types.rb +9 -9
- data/lib/pageflow/zencoder_api.rb +32 -42
- data/lib/pageflow/zencoder_audio_output_definition.rb +14 -13
- data/lib/pageflow/zencoder_meta_data_output_definition.rb +3 -2
- data/lib/pageflow/zencoder_output_definition.rb +16 -14
- data/lib/pageflow/zencoder_video_output_definition.rb +140 -88
- data/lib/pageflow.rb +8 -2
- data/lib/tasks/pageflow_tasks.rake +1 -1
- data/package/config/eslint-rules/documented-in-toc.js +125 -0
- data/package/config/jest/index.js +0 -1
- data/package/config/webpack.js +0 -1
- data/package/config/webpack5.js +0 -1
- data/package/editor.js +4880 -2313
- data/package/frontend.js +710 -1223
- data/package/package.json +3 -1
- data/package/review.js +384 -0
- data/package/testHelpers.js +257 -243
- data/package/ui.js +1487 -813
- data/package/vendor/stubs/wysihtml5.js +2 -0
- data/spec/factories/accounts.rb +37 -22
- data/spec/factories/audio_files.rb +2 -2
- data/spec/factories/authentication_tokens.rb +4 -4
- data/spec/factories/chapters.rb +4 -4
- data/spec/factories/comment_thread_reads.rb +10 -0
- data/spec/factories/comment_threads.rb +10 -0
- data/spec/factories/comments.rb +9 -0
- data/spec/factories/draft_entries.rb +14 -6
- data/spec/factories/edit_locks.rb +1 -1
- data/spec/factories/entries.rb +28 -19
- data/spec/factories/entry_translation_groups.rb +6 -0
- data/spec/factories/file_folders.rb +8 -0
- data/spec/factories/file_usages.rb +2 -1
- data/spec/factories/folders.rb +1 -1
- data/spec/factories/image_files.rb +2 -2
- data/spec/factories/pages.rb +3 -3
- data/spec/factories/published_entries.rb +28 -8
- data/spec/factories/revisions.rb +1 -1
- data/spec/factories/sites.rb +6 -0
- data/spec/factories/test_multi_attachment_files.rb +1 -1
- data/spec/factories/text_track_files.rb +1 -1
- data/spec/factories/uploadable_files.rb +1 -1
- data/spec/factories/users.rb +6 -6
- data/spec/factories/video_files.rb +2 -2
- data/spec/factories/widgets.rb +1 -1
- data/spec/fixtures/7x15_rotated.jpg +0 -0
- data/vendor/assets/javascripts/wysihtml-toolbar.js +19288 -0
- metadata +266 -92
- data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
- data/config/initializers/revision_components.rb +0 -5
- data/config/locales/twitter_to_x.de.yml +0 -6
- data/config/locales/twitter_to_x.en.yml +0 -6
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
- data/entry_types/scrolled/config/locales/twitter_to_x.de.yml +0 -12
- data/entry_types/scrolled/config/locales/twitter_to_x.en.yml +0 -12
- data/entry_types/scrolled/config/locales/vr_image_projection.de.yml +0 -24
- data/entry_types/scrolled/config/locales/vr_image_projection.en.yml +0 -24
- data/entry_types/scrolled/package/frontend/EditableInlineText.module-ebd22921.js +0 -5497
- data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-b79159cc.js +0 -107
- data/entry_types/scrolled/package/frontend/Viewer-1ecf3375.js +0 -154
- data/entry_types/scrolled/package/frontend/Wavesurfer-7d9cf1b7.js +0 -333
- data/entry_types/scrolled/package/frontend/arrowRight-62998af9.js +0 -77
- data/entry_types/scrolled/package/frontend/components-024a9893.js +0 -2853
- data/entry_types/scrolled/package/frontend/createSuper-d0f30da3.js +0 -115
- data/entry_types/scrolled/package/frontend/i18n-ce13a8bf.js +0 -1129
- data/entry_types/scrolled/package/frontend/useContentElementEditorState-4f4c3cf6.js +0 -52
- data/lib/generators/pageflow/resque/templates/resque_enqueue_after_commit_patch.rb +0 -25
- data/package/vendor/jquery.minicolors.js +0 -1108
data/package/ui.js
CHANGED
|
@@ -3,9 +3,9 @@ import _ from 'underscore';
|
|
|
3
3
|
import $ from 'jquery';
|
|
4
4
|
import I18n$1 from 'i18n-js';
|
|
5
5
|
import Backbone from 'backbone';
|
|
6
|
+
import Sortable from 'sortablejs';
|
|
6
7
|
import ChildViewContainer from 'backbone.babysitter';
|
|
7
8
|
import IScroll from 'iscroll';
|
|
8
|
-
import 'jquery.minicolors';
|
|
9
9
|
import wysihtml5 from 'wysihtml5';
|
|
10
10
|
import 'jquery-ui';
|
|
11
11
|
import Cocktail from 'cocktail';
|
|
@@ -16,15 +16,12 @@ Marionette.Renderer.render = function (template, data) {
|
|
|
16
16
|
if (_.isFunction(template)) {
|
|
17
17
|
return template(data);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
19
|
if (template.indexOf('templates/') === 0) {
|
|
21
20
|
template = 'pageflow/editor/' + template;
|
|
22
21
|
}
|
|
23
|
-
|
|
24
22
|
if (!JST[template]) {
|
|
25
23
|
throw "Template '" + template + "' not found!";
|
|
26
24
|
}
|
|
27
|
-
|
|
28
25
|
return JST[template](data);
|
|
29
26
|
};
|
|
30
27
|
|
|
@@ -50,22 +47,19 @@ Marionette.Renderer.render = function (template, data) {
|
|
|
50
47
|
* @memberof i18nUtils
|
|
51
48
|
* @since 12.0
|
|
52
49
|
*/
|
|
53
|
-
|
|
54
50
|
function attributeTranslationKeys(attributeName, keyName, options) {
|
|
55
51
|
var result = [];
|
|
56
|
-
|
|
57
52
|
if (options.prefixes) {
|
|
58
53
|
result = result.concat(_(options.prefixes).map(function (prefix) {
|
|
59
54
|
return prefix + '.' + attributeName + '.' + keyName;
|
|
60
55
|
}, this));
|
|
61
56
|
}
|
|
62
|
-
|
|
63
57
|
if (options && options.fallbackPrefix) {
|
|
64
58
|
result.push(options.fallbackPrefix + '.' + options.fallbackModelI18nKey + '.' + attributeName);
|
|
65
59
|
}
|
|
66
|
-
|
|
67
60
|
return result;
|
|
68
61
|
}
|
|
62
|
+
|
|
69
63
|
/**
|
|
70
64
|
* Takes the same parameters as {@link
|
|
71
65
|
* #i18nutilsattributetranslationkeys attributeTranslationKeys}, but returns the first existing
|
|
@@ -75,10 +69,10 @@ function attributeTranslationKeys(attributeName, keyName, options) {
|
|
|
75
69
|
* @memberof i18nUtils
|
|
76
70
|
* @since 12.0
|
|
77
71
|
*/
|
|
78
|
-
|
|
79
72
|
function attributeTranslation(attributeName, keyName, options) {
|
|
80
73
|
return findTranslation(attributeTranslationKeys(attributeName, keyName, options));
|
|
81
74
|
}
|
|
75
|
+
|
|
82
76
|
/**
|
|
83
77
|
* Find the first key for which a translation exists and return the
|
|
84
78
|
* translation.
|
|
@@ -97,19 +91,15 @@ function attributeTranslation(attributeName, keyName, options) {
|
|
|
97
91
|
* @memberof i18nUtils
|
|
98
92
|
* @return {string}
|
|
99
93
|
*/
|
|
100
|
-
|
|
101
94
|
function findTranslation(keys, options) {
|
|
102
95
|
options = options || {};
|
|
103
|
-
|
|
104
96
|
if (options.html) {
|
|
105
97
|
keys = translationKeysWithSuffix(keys, 'html');
|
|
106
98
|
}
|
|
107
|
-
|
|
108
99
|
return _.chain(keys).reverse().reduce(function (result, key) {
|
|
109
100
|
var unescapedTranslation = I18n$1.t(key, _.extend({}, options, {
|
|
110
101
|
defaultValue: result
|
|
111
102
|
}));
|
|
112
|
-
|
|
113
103
|
if (!options.html || key.match(/_html$/) || result == unescapedTranslation) {
|
|
114
104
|
return unescapedTranslation;
|
|
115
105
|
} else {
|
|
@@ -117,6 +107,7 @@ function findTranslation(keys, options) {
|
|
|
117
107
|
}
|
|
118
108
|
}, options.defaultValue).value();
|
|
119
109
|
}
|
|
110
|
+
|
|
120
111
|
/**
|
|
121
112
|
* Return the first key for which a translation exists. Returns the
|
|
122
113
|
* first if non of the keys has a translation.
|
|
@@ -127,7 +118,6 @@ function findTranslation(keys, options) {
|
|
|
127
118
|
* @memberof i18nUtils
|
|
128
119
|
* @return {string}
|
|
129
120
|
*/
|
|
130
|
-
|
|
131
121
|
function findKeyWithTranslation(keys) {
|
|
132
122
|
var missing = '_not_translated';
|
|
133
123
|
return _(keys).detect(function (key) {
|
|
@@ -151,64 +141,6 @@ var i18nUtils = /*#__PURE__*/Object.freeze({
|
|
|
151
141
|
translationKeysWithSuffix: translationKeysWithSuffix
|
|
152
142
|
});
|
|
153
143
|
|
|
154
|
-
function _arrayWithHoles(arr) {
|
|
155
|
-
if (Array.isArray(arr)) return arr;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function _iterableToArrayLimit(arr, i) {
|
|
159
|
-
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
|
|
160
|
-
var _arr = [];
|
|
161
|
-
var _n = true;
|
|
162
|
-
var _d = false;
|
|
163
|
-
var _e = undefined;
|
|
164
|
-
|
|
165
|
-
try {
|
|
166
|
-
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
|
167
|
-
_arr.push(_s.value);
|
|
168
|
-
|
|
169
|
-
if (i && _arr.length === i) break;
|
|
170
|
-
}
|
|
171
|
-
} catch (err) {
|
|
172
|
-
_d = true;
|
|
173
|
-
_e = err;
|
|
174
|
-
} finally {
|
|
175
|
-
try {
|
|
176
|
-
if (!_n && _i["return"] != null) _i["return"]();
|
|
177
|
-
} finally {
|
|
178
|
-
if (_d) throw _e;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return _arr;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function _arrayLikeToArray(arr, len) {
|
|
186
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
187
|
-
|
|
188
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) {
|
|
189
|
-
arr2[i] = arr[i];
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return arr2;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
196
|
-
if (!o) return;
|
|
197
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
198
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
199
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
200
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
201
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function _nonIterableRest() {
|
|
205
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function _slicedToArray(arr, i) {
|
|
209
|
-
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
|
|
210
|
-
}
|
|
211
|
-
|
|
212
144
|
/**
|
|
213
145
|
* Create object that can be passed to Marionette ui property from CSS
|
|
214
146
|
* module object.
|
|
@@ -248,16 +180,13 @@ function _slicedToArray(arr, i) {
|
|
|
248
180
|
*
|
|
249
181
|
* @memberof cssModulesUtils
|
|
250
182
|
*/
|
|
251
|
-
function ui(styles) {
|
|
252
|
-
|
|
253
|
-
classNames[_key - 1] = arguments[_key];
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return classNames.reduce(function (result, className) {
|
|
183
|
+
function ui(styles, ...classNames) {
|
|
184
|
+
return classNames.reduce((result, className) => {
|
|
257
185
|
result[className] = selector(styles, className);
|
|
258
186
|
return result;
|
|
259
187
|
}, {});
|
|
260
188
|
}
|
|
189
|
+
|
|
261
190
|
/**
|
|
262
191
|
* Create object that can be passed to Marionette events property from CSS
|
|
263
192
|
* module object.
|
|
@@ -295,18 +224,14 @@ function ui(styles) {
|
|
|
295
224
|
*
|
|
296
225
|
* @memberof cssModulesUtils
|
|
297
226
|
*/
|
|
298
|
-
|
|
299
227
|
function events(styles, mapping) {
|
|
300
|
-
return Object.keys(mapping).reduce(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
event = _key$split2[0],
|
|
304
|
-
className = _key$split2[1];
|
|
305
|
-
|
|
306
|
-
result["".concat(event, " ").concat(selector(styles, className))] = mapping[key];
|
|
228
|
+
return Object.keys(mapping).reduce((result, key) => {
|
|
229
|
+
const [event, className] = key.split(' ');
|
|
230
|
+
result[`${event} ${selector(styles, className)}`] = mapping[key];
|
|
307
231
|
return result;
|
|
308
232
|
}, {});
|
|
309
233
|
}
|
|
234
|
+
|
|
310
235
|
/**
|
|
311
236
|
* Generates a CSS selector from a CSS module rule.
|
|
312
237
|
*
|
|
@@ -319,15 +244,12 @@ function events(styles, mapping) {
|
|
|
319
244
|
* @return {String} CSS Selector
|
|
320
245
|
* @memberof cssModulesUtils
|
|
321
246
|
*/
|
|
322
|
-
|
|
323
247
|
function selector(styles, className) {
|
|
324
|
-
|
|
325
|
-
|
|
248
|
+
const classNames = styles[className];
|
|
326
249
|
if (!classNames) {
|
|
327
|
-
throw new Error(
|
|
250
|
+
throw new Error(`Unknown class name ${className} in mapping. Knwon names: ${Object.keys(styles).join(', ')}.`);
|
|
328
251
|
}
|
|
329
|
-
|
|
330
|
-
return ".".concat(classNames.replace(/ /g, '.'));
|
|
252
|
+
return `.${classNames.replace(/ /g, '.')}`;
|
|
331
253
|
}
|
|
332
254
|
|
|
333
255
|
var cssModulesUtils = /*#__PURE__*/Object.freeze({
|
|
@@ -337,46 +259,92 @@ var cssModulesUtils = /*#__PURE__*/Object.freeze({
|
|
|
337
259
|
selector: selector
|
|
338
260
|
});
|
|
339
261
|
|
|
262
|
+
function setup({
|
|
263
|
+
binding,
|
|
264
|
+
model,
|
|
265
|
+
listener,
|
|
266
|
+
callback,
|
|
267
|
+
normalize = value => value,
|
|
268
|
+
option,
|
|
269
|
+
bindingValue
|
|
270
|
+
}) {
|
|
271
|
+
if (binding) {
|
|
272
|
+
_.flatten([binding]).forEach(attribute => {
|
|
273
|
+
listener.listenTo(model, 'change:' + attribute, update);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
update();
|
|
277
|
+
function update() {
|
|
278
|
+
callback(resolve({
|
|
279
|
+
binding,
|
|
280
|
+
model,
|
|
281
|
+
normalize,
|
|
282
|
+
option,
|
|
283
|
+
bindingValue
|
|
284
|
+
}));
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function resolve({
|
|
288
|
+
binding,
|
|
289
|
+
model,
|
|
290
|
+
normalize = value => value,
|
|
291
|
+
option,
|
|
292
|
+
bindingValue
|
|
293
|
+
}) {
|
|
294
|
+
const boundValue = Array.isArray(binding) ? binding.map(attribute => model.get(attribute)) : model.get(binding);
|
|
295
|
+
if (bindingValue !== undefined) {
|
|
296
|
+
return boundValue === bindingValue;
|
|
297
|
+
} else if (typeof option === 'function') {
|
|
298
|
+
return normalize(option(boundValue));
|
|
299
|
+
} else if (option !== undefined) {
|
|
300
|
+
return normalize(option);
|
|
301
|
+
} else if (binding) {
|
|
302
|
+
return normalize(boundValue);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
var attributeBindingUtils = /*#__PURE__*/Object.freeze({
|
|
307
|
+
__proto__: null,
|
|
308
|
+
setup: setup,
|
|
309
|
+
resolve: resolve
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Class-y constructor by github.com/opensas
|
|
340
313
|
// https://github.com/jashkenas/backbone/issues/2601
|
|
341
314
|
|
|
342
315
|
function BaseObject(options) {
|
|
343
316
|
this.initialize.apply(this, arguments);
|
|
344
317
|
}
|
|
345
|
-
|
|
346
318
|
_.extend(BaseObject.prototype, Backbone.Events, {
|
|
347
|
-
initialize: function
|
|
348
|
-
});
|
|
349
|
-
|
|
319
|
+
initialize: function (options) {}
|
|
320
|
+
});
|
|
350
321
|
|
|
322
|
+
// The self-propagating extend function that Backbone classes use.
|
|
351
323
|
BaseObject.extend = Backbone.Model.extend;
|
|
352
324
|
|
|
353
|
-
|
|
354
|
-
initialize
|
|
355
|
-
var _this = this;
|
|
356
|
-
|
|
325
|
+
const serverSideValidation = {
|
|
326
|
+
initialize() {
|
|
357
327
|
this.validationErrors = {};
|
|
358
|
-
this.listenTo(this, 'error',
|
|
328
|
+
this.listenTo(this, 'error', (model, request) => {
|
|
359
329
|
if (request.status === 422) {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
_this.trigger('invalid');
|
|
330
|
+
this.validationErrors = JSON.parse(request.responseText).errors;
|
|
331
|
+
this.trigger('invalid');
|
|
363
332
|
}
|
|
364
333
|
});
|
|
365
|
-
this.listenTo(this, 'sync',
|
|
366
|
-
|
|
334
|
+
this.listenTo(this, 'sync', () => {
|
|
335
|
+
this.validationErrors = {};
|
|
367
336
|
});
|
|
368
337
|
}
|
|
369
338
|
};
|
|
370
339
|
|
|
371
|
-
|
|
372
|
-
initialize: function
|
|
340
|
+
const CollectionView = Marionette.View.extend({
|
|
341
|
+
initialize: function () {
|
|
373
342
|
this.rendered = false;
|
|
374
343
|
this.itemViews = new ChildViewContainer();
|
|
375
344
|
this.collection.map(this.addItem, this);
|
|
376
345
|
this.listenTo(this.collection, 'add', this.addItem);
|
|
377
346
|
this.listenTo(this.collection, 'remove', this.removeItem);
|
|
378
347
|
this.listenTo(this.collection, 'sort', this.sort);
|
|
379
|
-
|
|
380
348
|
if (this.options.loadingViewConstructor) {
|
|
381
349
|
this.listenTo(this.collection, 'request', function () {
|
|
382
350
|
this.loading = true;
|
|
@@ -388,7 +356,7 @@ var CollectionView = Marionette.View.extend({
|
|
|
388
356
|
});
|
|
389
357
|
}
|
|
390
358
|
},
|
|
391
|
-
render: function
|
|
359
|
+
render: function () {
|
|
392
360
|
if (!this.rendered) {
|
|
393
361
|
this.$el.append(this.itemViews.map(function (itemView) {
|
|
394
362
|
itemView.$el.data('view', itemView);
|
|
@@ -397,89 +365,84 @@ var CollectionView = Marionette.View.extend({
|
|
|
397
365
|
this.togglePlaceHolder();
|
|
398
366
|
this.rendered = true;
|
|
399
367
|
}
|
|
400
|
-
|
|
401
368
|
return this;
|
|
402
369
|
},
|
|
403
|
-
onClose: function
|
|
370
|
+
onClose: function () {
|
|
404
371
|
this.itemViews.call('close');
|
|
405
372
|
this.closePlaceHolderView();
|
|
406
373
|
},
|
|
407
|
-
addItem: function
|
|
374
|
+
addItem: function (item) {
|
|
408
375
|
var view = new this.options.itemViewConstructor(_.extend({
|
|
409
376
|
model: item
|
|
410
377
|
}, this.getItemViewOptions(item)));
|
|
411
378
|
this.itemViews.add(view);
|
|
412
|
-
|
|
413
379
|
if (this.rendered) {
|
|
414
380
|
var index = this.collection.indexOf(item);
|
|
415
381
|
view.render();
|
|
416
382
|
view.$el.data('view', view);
|
|
417
|
-
|
|
418
383
|
if (index > 0) {
|
|
419
384
|
this.$el.children().eq(index - 1).after(view.el);
|
|
420
385
|
} else {
|
|
421
386
|
this.$el.prepend(view.el);
|
|
422
387
|
}
|
|
423
|
-
|
|
424
388
|
this.togglePlaceHolder();
|
|
425
389
|
}
|
|
426
390
|
},
|
|
427
|
-
removeItem: function
|
|
391
|
+
removeItem: function (item) {
|
|
428
392
|
var view = this.itemViews.findByModel(item);
|
|
429
|
-
|
|
430
393
|
if (view) {
|
|
431
394
|
this.itemViews.remove(view);
|
|
432
395
|
view.close();
|
|
433
396
|
this.togglePlaceHolder();
|
|
434
397
|
}
|
|
435
398
|
},
|
|
436
|
-
sort: function
|
|
399
|
+
sort: function () {
|
|
437
400
|
var last = null;
|
|
438
401
|
this.collection.each(function (item) {
|
|
439
402
|
var itemView = this.itemViews.findByModel(item);
|
|
440
403
|
var element;
|
|
441
|
-
|
|
442
404
|
if (!itemView) {
|
|
443
405
|
return;
|
|
444
406
|
}
|
|
445
|
-
|
|
446
407
|
element = itemView.$el;
|
|
447
|
-
|
|
448
408
|
if (last) {
|
|
449
409
|
last.after(element);
|
|
450
410
|
} else {
|
|
451
411
|
this.$el.prepend(element);
|
|
452
412
|
}
|
|
453
|
-
|
|
454
413
|
last = element;
|
|
455
414
|
}, this);
|
|
456
415
|
},
|
|
457
|
-
getItemViewOptions: function
|
|
416
|
+
getItemViewOptions: function (item) {
|
|
458
417
|
if (typeof this.options.itemViewOptions === 'function') {
|
|
459
418
|
return this.options.itemViewOptions(item);
|
|
460
419
|
} else {
|
|
461
420
|
return this.options.itemViewOptions || {};
|
|
462
421
|
}
|
|
463
422
|
},
|
|
464
|
-
closePlaceHolderView: function
|
|
423
|
+
closePlaceHolderView: function () {
|
|
465
424
|
if (this.placeHolderView) {
|
|
466
425
|
this.placeHolderView.close();
|
|
467
426
|
this.placeHolderView = null;
|
|
468
427
|
}
|
|
469
428
|
},
|
|
470
|
-
togglePlaceHolder: function
|
|
429
|
+
togglePlaceHolder: function () {
|
|
471
430
|
var lastPlaceholderConstructor = this.placeHolderConstructor;
|
|
472
431
|
this.placeHolderConstructor = this.getPlaceHolderConstructor();
|
|
473
|
-
|
|
474
432
|
if (this.itemViews.length || !this.placeHolderConstructor) {
|
|
475
433
|
this.closePlaceHolderView();
|
|
476
434
|
} else if (!this.placeHolderView || lastPlaceholderConstructor !== this.placeHolderConstructor) {
|
|
477
435
|
this.closePlaceHolderView();
|
|
478
|
-
this.placeHolderView = new this.placeHolderConstructor();
|
|
436
|
+
this.placeHolderView = new this.placeHolderConstructor(this.getPlaceHolderViewOptions());
|
|
479
437
|
this.$el.append(this.placeHolderView.render().el);
|
|
480
438
|
}
|
|
481
439
|
},
|
|
482
|
-
|
|
440
|
+
getPlaceHolderViewOptions: function () {
|
|
441
|
+
if (this.placeHolderConstructor === this.options.blankSlateViewConstructor) {
|
|
442
|
+
return this.options.blankSlateViewOptions;
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
getPlaceHolderConstructor: function () {
|
|
483
446
|
if (this.loading && this.options.loadingViewConstructor) {
|
|
484
447
|
return this.options.loadingViewConstructor;
|
|
485
448
|
} else if (this.options.blankSlateViewConstructor) {
|
|
@@ -488,119 +451,135 @@ var CollectionView = Marionette.View.extend({
|
|
|
488
451
|
}
|
|
489
452
|
});
|
|
490
453
|
|
|
491
|
-
|
|
492
|
-
render: function
|
|
454
|
+
const SortableCollectionView = CollectionView.extend({
|
|
455
|
+
render: function () {
|
|
493
456
|
CollectionView.prototype.render.call(this);
|
|
494
|
-
this
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
457
|
+
this.sortable = Sortable.create(this.el, {
|
|
458
|
+
group: this.options.connectWith,
|
|
459
|
+
animation: 150,
|
|
460
|
+
ghostClass: 'sortable-placeholder',
|
|
461
|
+
forceFallback: this.options.forceDraggableFallback,
|
|
462
|
+
fallbackTolerance: 3,
|
|
463
|
+
onEnd: event => {
|
|
464
|
+
const item = $(event.item);
|
|
465
|
+
if (item.parent().is(this.el)) {
|
|
501
466
|
this.updateOrder();
|
|
502
467
|
}
|
|
503
|
-
},
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
this.reindexPositions();
|
|
507
|
-
this.itemViews.add(view);
|
|
508
|
-
this.collection.add(view.model);
|
|
509
|
-
}, this),
|
|
510
|
-
remove: _.bind(function (event, ui) {
|
|
511
|
-
var view = ui.item.data('view');
|
|
468
|
+
},
|
|
469
|
+
onRemove: event => {
|
|
470
|
+
const view = $(event.item).data('view');
|
|
512
471
|
this.itemViews.remove(view);
|
|
513
472
|
this.collection.remove(view.model);
|
|
514
|
-
},
|
|
473
|
+
},
|
|
474
|
+
onSort: event => {
|
|
475
|
+
if (event.from !== event.to && event.to === this.el) {
|
|
476
|
+
const view = $(event.item).data('view');
|
|
477
|
+
this.reindexPositions();
|
|
478
|
+
this.itemViews.add(view);
|
|
479
|
+
this.collection.add(view.model);
|
|
480
|
+
this.collection.saveOrder();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
515
483
|
});
|
|
516
484
|
return this;
|
|
517
485
|
},
|
|
518
|
-
|
|
486
|
+
onClose() {
|
|
487
|
+
CollectionView.prototype.onClose.call(this);
|
|
488
|
+
this.sortable.destroy();
|
|
489
|
+
},
|
|
490
|
+
disableSorting() {
|
|
491
|
+
this.sortable.option('disabled', true);
|
|
492
|
+
},
|
|
493
|
+
enableSorting() {
|
|
494
|
+
this.sortable.option('disabled', false);
|
|
495
|
+
},
|
|
496
|
+
addItem: function (item) {
|
|
519
497
|
if (!this.itemViews.findByModel(item)) {
|
|
520
498
|
CollectionView.prototype.addItem.call(this, item);
|
|
521
499
|
}
|
|
522
500
|
},
|
|
523
|
-
removeItem: function
|
|
501
|
+
removeItem: function (item) {
|
|
524
502
|
if (this.itemViews.findByModel(item)) {
|
|
525
503
|
CollectionView.prototype.removeItem.call(this, item);
|
|
526
504
|
}
|
|
527
505
|
},
|
|
528
|
-
updateOrder: function
|
|
506
|
+
updateOrder: function () {
|
|
529
507
|
this.reindexPositions();
|
|
530
508
|
this.collection.sort();
|
|
531
509
|
this.collection.saveOrder();
|
|
532
510
|
},
|
|
533
|
-
reindexPositions: function
|
|
511
|
+
reindexPositions: function () {
|
|
534
512
|
this.$el.children().each(function (index) {
|
|
535
513
|
$(this).data('view').model.set('position', index);
|
|
536
514
|
});
|
|
537
515
|
}
|
|
538
516
|
});
|
|
539
517
|
|
|
540
|
-
|
|
518
|
+
const ConfigurationEditorTabView = Marionette.View.extend({
|
|
541
519
|
className: 'configuration_editor_tab',
|
|
542
|
-
initialize: function
|
|
520
|
+
initialize: function () {
|
|
543
521
|
this.inputs = new ChildViewContainer();
|
|
544
522
|
this.groups = this.options.groups || ConfigurationEditorTabView.groups;
|
|
545
523
|
},
|
|
546
|
-
input: function
|
|
524
|
+
input: function (propertyName, view, options) {
|
|
547
525
|
this.view(view, _.extend({
|
|
548
526
|
placeholderModel: this.options.placeholderModel,
|
|
549
527
|
propertyName: propertyName,
|
|
550
528
|
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
|
|
551
529
|
}, options || {}));
|
|
552
530
|
},
|
|
553
|
-
view: function view
|
|
554
|
-
this.inputs.add(new
|
|
531
|
+
view: function (view, options) {
|
|
532
|
+
this.inputs.add(new view(_.extend({
|
|
555
533
|
model: this.model,
|
|
556
534
|
parentTab: this.options.tab
|
|
557
535
|
}, options || {})));
|
|
558
536
|
},
|
|
559
|
-
group: function
|
|
537
|
+
group: function (name, options) {
|
|
560
538
|
this.groups.apply(name, this, options);
|
|
561
539
|
},
|
|
562
|
-
render: function
|
|
540
|
+
render: function () {
|
|
563
541
|
this.inputs.each(function (input) {
|
|
564
542
|
this.$el.append(input.render().el);
|
|
565
543
|
}, this);
|
|
566
544
|
return this;
|
|
567
545
|
},
|
|
568
|
-
onClose: function
|
|
546
|
+
onClose: function () {
|
|
569
547
|
if (this.inputs) {
|
|
570
548
|
this.inputs.call('close');
|
|
571
549
|
}
|
|
572
550
|
}
|
|
573
551
|
});
|
|
574
|
-
|
|
575
552
|
ConfigurationEditorTabView.Groups = function () {
|
|
576
553
|
var groups = {};
|
|
577
|
-
|
|
578
554
|
this.define = function (name, fn) {
|
|
579
555
|
if (typeof fn !== 'function') {
|
|
580
556
|
throw 'Group has to be function.';
|
|
581
557
|
}
|
|
582
|
-
|
|
583
558
|
groups[name] = fn;
|
|
584
559
|
};
|
|
585
|
-
|
|
586
|
-
|
|
560
|
+
this.apply = function (name, context, {
|
|
561
|
+
ignoreUndefined,
|
|
562
|
+
...options
|
|
563
|
+
} = {}) {
|
|
587
564
|
if (!(name in groups)) {
|
|
565
|
+
if (ignoreUndefined) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
588
568
|
throw 'Undefined group named "' + name + '".';
|
|
589
569
|
}
|
|
590
|
-
|
|
591
570
|
groups[name].call(context, options || {});
|
|
592
571
|
};
|
|
593
572
|
};
|
|
594
|
-
|
|
595
573
|
ConfigurationEditorTabView.groups = new ConfigurationEditorTabView.Groups();
|
|
596
574
|
|
|
597
575
|
function template(data) {
|
|
598
576
|
var __p = '';
|
|
599
|
-
__p += '<div class="tabs_view-scroller">\n <
|
|
577
|
+
__p += '<div class="tabs_view-scroller">\n <div class="tabs_view-tabs" role="tablist" aria-orientation="horizontal"></div>\n</div>\n<div class="tabs_view-container"></div>\n';
|
|
600
578
|
return __p
|
|
601
579
|
}
|
|
602
580
|
|
|
603
581
|
/*global pageflow*/
|
|
582
|
+
|
|
604
583
|
/**
|
|
605
584
|
* Switch between different views using tabs.
|
|
606
585
|
*
|
|
@@ -621,41 +600,43 @@ return __p
|
|
|
621
600
|
*
|
|
622
601
|
* @class
|
|
623
602
|
*/
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
/* @lends TabView.prototype */
|
|
627
|
-
{
|
|
628
|
-
template: template,
|
|
603
|
+
const TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
604
|
+
template,
|
|
629
605
|
className: 'tabs_view',
|
|
630
606
|
ui: {
|
|
631
|
-
|
|
632
|
-
scroller: '.tabs_view-scroller'
|
|
607
|
+
tabs: '.tabs_view-tabs',
|
|
608
|
+
scroller: '.tabs_view-scroller',
|
|
609
|
+
container: '.tabs_view-container'
|
|
633
610
|
},
|
|
634
611
|
regions: {
|
|
635
612
|
container: '.tabs_view-container'
|
|
636
613
|
},
|
|
637
614
|
events: {
|
|
638
|
-
'click .tabs_view-
|
|
639
|
-
this.changeTab($(event.
|
|
615
|
+
'click .tabs_view-tab': function (event) {
|
|
616
|
+
this.changeTab($(event.currentTarget).data('tab-name'));
|
|
617
|
+
},
|
|
618
|
+
'keydown .tabs_view-tab': function (event) {
|
|
619
|
+
this._handleKeyDown(event);
|
|
640
620
|
}
|
|
641
621
|
},
|
|
642
|
-
initialize: function
|
|
622
|
+
initialize: function () {
|
|
643
623
|
this.tabFactoryFns = {};
|
|
644
624
|
this.tabNames = [];
|
|
645
625
|
this.currentTabName = null;
|
|
646
|
-
|
|
647
626
|
this._refreshScrollerOnSideBarResize();
|
|
648
627
|
},
|
|
649
|
-
tab: function
|
|
628
|
+
tab: function (name, factoryFn) {
|
|
650
629
|
this.tabFactoryFns[name] = factoryFn;
|
|
651
630
|
this.tabNames.push(name);
|
|
652
631
|
},
|
|
653
|
-
onRender: function
|
|
632
|
+
onRender: function () {
|
|
654
633
|
_.each(this.tabNames, function (name) {
|
|
655
634
|
var label = findTranslation(this._labelTranslationKeys(name));
|
|
656
|
-
this.
|
|
635
|
+
var tabId = this._tabId(name);
|
|
636
|
+
var button = $('<button />').attr('type', 'button').attr('role', 'tab').attr('id', tabId).attr('data-tab-name', name).attr('tabindex', '-1').attr('aria-selected', 'false').addClass('tabs_view-tab').text(label);
|
|
637
|
+
this.ui.tabs.append(button);
|
|
657
638
|
}, this);
|
|
658
|
-
|
|
639
|
+
this.ui.container.attr('id', this._panelId()).attr('role', 'tabpanel');
|
|
659
640
|
this.scroller = new IScroll(this.ui.scroller[0], {
|
|
660
641
|
scrollX: true,
|
|
661
642
|
scrollY: false,
|
|
@@ -663,71 +644,138 @@ var TabsView = Marionette.Layout.extend(
|
|
|
663
644
|
mouseWheel: true,
|
|
664
645
|
preventDefault: false
|
|
665
646
|
});
|
|
666
|
-
this.changeTab(this.defaultTab()
|
|
647
|
+
this.changeTab(this.defaultTab(), {
|
|
648
|
+
refresh: true
|
|
649
|
+
});
|
|
667
650
|
},
|
|
668
|
-
changeTab: function
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
651
|
+
changeTab: function (name, options = {}) {
|
|
652
|
+
if (!this.tabFactoryFns[name]) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
if (this.currentTabName !== name || options.refresh) {
|
|
656
|
+
this.container.show(this.tabFactoryFns[name]());
|
|
657
|
+
}
|
|
673
658
|
this.currentTabName = name;
|
|
659
|
+
this._updateActiveTab(name, options.focusTab);
|
|
660
|
+
this._updateActivePanel(name);
|
|
674
661
|
},
|
|
675
|
-
defaultTab: function
|
|
662
|
+
defaultTab: function () {
|
|
676
663
|
if (_.include(this.tabNames, this.options.defaultTab)) {
|
|
677
664
|
return this.options.defaultTab;
|
|
678
665
|
} else {
|
|
679
666
|
return _.first(this.tabNames);
|
|
680
667
|
}
|
|
681
668
|
},
|
|
682
|
-
|
|
683
669
|
/**
|
|
684
670
|
* Rerender current tab.
|
|
685
671
|
*/
|
|
686
|
-
refresh: function
|
|
687
|
-
|
|
672
|
+
refresh: function () {
|
|
673
|
+
if (this.currentTabName) {
|
|
674
|
+
this.changeTab(this.currentTabName, {
|
|
675
|
+
refresh: true
|
|
676
|
+
});
|
|
677
|
+
}
|
|
688
678
|
},
|
|
689
|
-
|
|
690
679
|
/**
|
|
691
680
|
* Adjust tabs scroller to changed width of view.
|
|
692
681
|
*/
|
|
693
|
-
refreshScroller: function
|
|
682
|
+
refreshScroller: function () {
|
|
694
683
|
this.scroller.refresh();
|
|
695
684
|
},
|
|
696
|
-
toggleSpinnerOnTab: function
|
|
685
|
+
toggleSpinnerOnTab: function (name, visible) {
|
|
697
686
|
this.$('[data-tab-name=' + name + ']').toggleClass('spinner', visible);
|
|
698
687
|
},
|
|
699
|
-
_labelTranslationKeys: function
|
|
688
|
+
_labelTranslationKeys: function (name) {
|
|
700
689
|
var result = _.map(this.options.translationKeyPrefixes, function (prefix) {
|
|
701
690
|
return prefix + '.' + name;
|
|
702
691
|
});
|
|
703
|
-
|
|
704
692
|
if (this.options.i18n) {
|
|
705
693
|
result.push(this.options.i18n + '.' + name);
|
|
706
694
|
}
|
|
707
|
-
|
|
708
695
|
if (this.options.fallbackTranslationKeyPrefix) {
|
|
709
696
|
result.push(this.options.fallbackTranslationKeyPrefix + '.' + name);
|
|
710
697
|
}
|
|
711
|
-
|
|
712
698
|
return result;
|
|
713
699
|
},
|
|
714
|
-
|
|
700
|
+
_updateActiveTab: function (activeTabName, focusTab) {
|
|
715
701
|
var scroller = this.scroller;
|
|
716
|
-
this.
|
|
717
|
-
|
|
702
|
+
var panelId = this._panelId();
|
|
703
|
+
this.ui.tabs.children().each(function () {
|
|
704
|
+
var button = $(this);
|
|
705
|
+
var isActive = button.data('tab-name') === activeTabName;
|
|
706
|
+
if (isActive) {
|
|
718
707
|
scroller.scrollToElement(this, 200, true);
|
|
719
|
-
|
|
708
|
+
button.addClass('active');
|
|
709
|
+
button.attr('aria-selected', 'true');
|
|
710
|
+
button.attr('aria-controls', panelId);
|
|
711
|
+
button.attr('tabindex', '0');
|
|
712
|
+
if (focusTab) {
|
|
713
|
+
button.focus();
|
|
714
|
+
}
|
|
720
715
|
} else {
|
|
721
|
-
|
|
716
|
+
button.removeClass('active');
|
|
717
|
+
button.attr('aria-selected', 'false');
|
|
718
|
+
button.attr('tabindex', '-1');
|
|
722
719
|
}
|
|
723
720
|
});
|
|
724
721
|
},
|
|
725
|
-
|
|
722
|
+
_updateActivePanel: function (activeTabName) {
|
|
723
|
+
this.ui.container.attr('aria-labelledby', this._tabId(activeTabName));
|
|
724
|
+
},
|
|
725
|
+
_handleKeyDown: function (event) {
|
|
726
|
+
var tabName = $(event.currentTarget).data('tab-name');
|
|
727
|
+
var nextTabName;
|
|
728
|
+
switch (event.key) {
|
|
729
|
+
case 'ArrowLeft':
|
|
730
|
+
case 'ArrowUp':
|
|
731
|
+
nextTabName = this._previousTabName(tabName);
|
|
732
|
+
break;
|
|
733
|
+
case 'ArrowRight':
|
|
734
|
+
case 'ArrowDown':
|
|
735
|
+
nextTabName = this._nextTabName(tabName);
|
|
736
|
+
break;
|
|
737
|
+
case 'Home':
|
|
738
|
+
nextTabName = _.first(this.tabNames);
|
|
739
|
+
break;
|
|
740
|
+
case 'End':
|
|
741
|
+
nextTabName = _.last(this.tabNames);
|
|
742
|
+
break;
|
|
743
|
+
case 'Enter':
|
|
744
|
+
case ' ':
|
|
745
|
+
nextTabName = tabName;
|
|
746
|
+
break;
|
|
747
|
+
default:
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
event.preventDefault();
|
|
751
|
+
if (nextTabName) {
|
|
752
|
+
this.changeTab(nextTabName, {
|
|
753
|
+
focusTab: true
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
},
|
|
757
|
+
_previousTabName: function (currentTabName) {
|
|
758
|
+
var currentIndex = _.indexOf(this.tabNames, currentTabName);
|
|
759
|
+
var previousIndex = (currentIndex - 1 + this.tabNames.length) % this.tabNames.length;
|
|
760
|
+
return this.tabNames[previousIndex];
|
|
761
|
+
},
|
|
762
|
+
_nextTabName: function (currentTabName) {
|
|
763
|
+
var currentIndex = _.indexOf(this.tabNames, currentTabName);
|
|
764
|
+
var nextIndex = (currentIndex + 1) % this.tabNames.length;
|
|
765
|
+
return this.tabNames[nextIndex];
|
|
766
|
+
},
|
|
767
|
+
_refreshScrollerOnSideBarResize: function () {
|
|
726
768
|
if (pageflow.app) {
|
|
727
769
|
this.listenTo(pageflow.app, 'resize', function () {
|
|
728
770
|
this.scroller.refresh();
|
|
729
771
|
});
|
|
730
772
|
}
|
|
773
|
+
},
|
|
774
|
+
_tabId: function (name) {
|
|
775
|
+
return this.cid + '-tab-' + name;
|
|
776
|
+
},
|
|
777
|
+
_panelId: function () {
|
|
778
|
+
return this.cid + '-panel';
|
|
731
779
|
}
|
|
732
780
|
});
|
|
733
781
|
|
|
@@ -756,10 +804,9 @@ var TabsView = Marionette.Layout.extend(
|
|
|
756
804
|
*
|
|
757
805
|
* @class
|
|
758
806
|
*/
|
|
759
|
-
|
|
760
|
-
var ConfigurationEditorView = Marionette.View.extend({
|
|
807
|
+
const ConfigurationEditorView = Marionette.View.extend({
|
|
761
808
|
className: 'configuration_editor',
|
|
762
|
-
initialize: function
|
|
809
|
+
initialize: function () {
|
|
763
810
|
this.tabsView = new TabsView({
|
|
764
811
|
translationKeyPrefixes: this.options.tabTranslationKeyPrefixes || [this.options.tabTranslationKeyPrefix],
|
|
765
812
|
fallbackTranslationKeyPrefix: 'pageflow.ui.configuration_editor.tabs',
|
|
@@ -767,10 +814,10 @@ var ConfigurationEditorView = Marionette.View.extend({
|
|
|
767
814
|
});
|
|
768
815
|
this.configure();
|
|
769
816
|
},
|
|
770
|
-
configure: function
|
|
771
|
-
tab: function
|
|
817
|
+
configure: function () {},
|
|
818
|
+
tab: function (name, callbackOrOptions, callback) {
|
|
772
819
|
callback = callback || callbackOrOptions;
|
|
773
|
-
|
|
820
|
+
const options = callback ? callbackOrOptions : {};
|
|
774
821
|
this.tabsView.tab(name, _.bind(function () {
|
|
775
822
|
var tabView = new ConfigurationEditorTabView({
|
|
776
823
|
model: options.model || this.model,
|
|
@@ -782,29 +829,26 @@ var ConfigurationEditorView = Marionette.View.extend({
|
|
|
782
829
|
return tabView;
|
|
783
830
|
}, this));
|
|
784
831
|
},
|
|
785
|
-
|
|
786
832
|
/**
|
|
787
833
|
* Rerender current tab.
|
|
788
834
|
*/
|
|
789
|
-
refresh: function
|
|
835
|
+
refresh: function () {
|
|
790
836
|
this.tabsView.refresh();
|
|
791
837
|
},
|
|
792
|
-
|
|
793
838
|
/**
|
|
794
839
|
* Adjust tabs scroller to changed width of view.
|
|
795
840
|
*/
|
|
796
|
-
refreshScroller: function
|
|
841
|
+
refreshScroller: function () {
|
|
797
842
|
this.tabsView.refreshScroller();
|
|
798
843
|
},
|
|
799
|
-
render: function
|
|
844
|
+
render: function () {
|
|
800
845
|
this.$el.append(this.subview(this.tabsView).el);
|
|
801
846
|
return this;
|
|
802
847
|
}
|
|
803
848
|
});
|
|
804
|
-
|
|
805
849
|
_.extend(ConfigurationEditorView, {
|
|
806
850
|
repository: {},
|
|
807
|
-
register: function
|
|
851
|
+
register: function (pageTypeName, prototype) {
|
|
808
852
|
this.repository[pageTypeName] = ConfigurationEditorView.extend(prototype);
|
|
809
853
|
}
|
|
810
854
|
});
|
|
@@ -829,44 +873,40 @@ return __p
|
|
|
829
873
|
*
|
|
830
874
|
* @since 12.0
|
|
831
875
|
*/
|
|
832
|
-
|
|
833
|
-
var TableCellView = Marionette.ItemView.extend({
|
|
876
|
+
const TableCellView = Marionette.ItemView.extend({
|
|
834
877
|
tagName: 'td',
|
|
835
878
|
template: template$1,
|
|
836
|
-
className: function
|
|
879
|
+
className: function () {
|
|
837
880
|
return this.options.className;
|
|
838
881
|
},
|
|
839
|
-
onRender: function
|
|
882
|
+
onRender: function () {
|
|
840
883
|
this.listenTo(this.getModel(), 'change:' + this.options.column.name, this.update);
|
|
841
884
|
this.setupContentBinding();
|
|
842
885
|
this.update();
|
|
843
886
|
},
|
|
844
|
-
|
|
845
887
|
/**
|
|
846
888
|
* Override in concrete cell view.
|
|
847
889
|
*/
|
|
848
|
-
update: function
|
|
890
|
+
update: function () {
|
|
849
891
|
throw 'Not implemented';
|
|
850
892
|
},
|
|
851
|
-
|
|
852
893
|
/**
|
|
853
894
|
* Returns the column attribute's value in the row model.
|
|
854
895
|
*/
|
|
855
|
-
attributeValue: function
|
|
896
|
+
attributeValue: function () {
|
|
856
897
|
if (typeof this.options.column.value == 'function') {
|
|
857
898
|
return this.options.column.value(this.model);
|
|
858
899
|
} else {
|
|
859
900
|
return this.getModel().get(this.options.column.name);
|
|
860
901
|
}
|
|
861
902
|
},
|
|
862
|
-
getModel: function
|
|
903
|
+
getModel: function () {
|
|
863
904
|
if (this.options.column.configurationAttribute) {
|
|
864
905
|
return this.model.configuration;
|
|
865
906
|
} else {
|
|
866
907
|
return this.model;
|
|
867
908
|
}
|
|
868
909
|
},
|
|
869
|
-
|
|
870
910
|
/**
|
|
871
911
|
* Look up attribute specific translations based on
|
|
872
912
|
* `attributeTranslationKeyPrefixes` of the the parent `TableView`.
|
|
@@ -885,15 +925,14 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
885
925
|
* // Looks for keys of the form:
|
|
886
926
|
* // <table_view_translation_key_prefix>.<column_attribute>.cell_title
|
|
887
927
|
*/
|
|
888
|
-
attributeTranslation: function
|
|
928
|
+
attributeTranslation: function (keyName, options) {
|
|
889
929
|
return findTranslation(this.attributeTranslationKeys(keyName), options);
|
|
890
930
|
},
|
|
891
|
-
attributeTranslationKeys: function
|
|
931
|
+
attributeTranslationKeys: function (keyName) {
|
|
892
932
|
return _(this.options.attributeTranslationKeyPrefixes || []).map(function (prefix) {
|
|
893
933
|
return prefix + '.' + this.options.column.name + '.' + keyName;
|
|
894
934
|
}, this);
|
|
895
935
|
},
|
|
896
|
-
|
|
897
936
|
/**
|
|
898
937
|
* Set up content binding to update this view upon change of
|
|
899
938
|
* specified attribute on this.getModel().
|
|
@@ -903,7 +942,7 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
903
942
|
*
|
|
904
943
|
* @protected
|
|
905
944
|
*/
|
|
906
|
-
setupContentBinding: function
|
|
945
|
+
setupContentBinding: function () {
|
|
907
946
|
if (this.options.column.contentBinding) {
|
|
908
947
|
this.listenTo(this.getModel(), 'change:' + this.options.column.contentBinding, this.update);
|
|
909
948
|
this.update();
|
|
@@ -911,30 +950,30 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
911
950
|
}
|
|
912
951
|
});
|
|
913
952
|
|
|
914
|
-
|
|
953
|
+
const TableHeaderCellView = TableCellView.extend({
|
|
915
954
|
tagName: 'th',
|
|
916
|
-
render: function
|
|
955
|
+
render: function () {
|
|
917
956
|
this.$el.text(this.options.column.headerText || this.attributeTranslation('column_header'));
|
|
918
957
|
this.$el.data('columnName', this.options.column.name);
|
|
919
958
|
return this;
|
|
920
959
|
}
|
|
921
960
|
});
|
|
922
961
|
|
|
923
|
-
|
|
962
|
+
const TableRowView = Marionette.View.extend({
|
|
924
963
|
tagName: 'tr',
|
|
925
964
|
events: {
|
|
926
|
-
'click': function
|
|
965
|
+
'click': function () {
|
|
927
966
|
if (this.options.selection) {
|
|
928
967
|
this.options.selection.set(this.selectionAttribute(), this.model);
|
|
929
968
|
}
|
|
930
969
|
}
|
|
931
970
|
},
|
|
932
|
-
initialize: function
|
|
971
|
+
initialize: function () {
|
|
933
972
|
if (this.options.selection) {
|
|
934
973
|
this.listenTo(this.options.selection, 'change', this.updateClassName);
|
|
935
974
|
}
|
|
936
975
|
},
|
|
937
|
-
render: function
|
|
976
|
+
render: function () {
|
|
938
977
|
_(this.options.columns).each(function (column) {
|
|
939
978
|
this.appendSubview(new column.cellView(_.extend({
|
|
940
979
|
model: this.model,
|
|
@@ -942,17 +981,16 @@ var TableRowView = Marionette.View.extend({
|
|
|
942
981
|
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
|
|
943
982
|
}, column.cellViewOptions || {})));
|
|
944
983
|
}, this);
|
|
945
|
-
|
|
946
984
|
this.updateClassName();
|
|
947
985
|
return this;
|
|
948
986
|
},
|
|
949
|
-
updateClassName: function
|
|
987
|
+
updateClassName: function () {
|
|
950
988
|
this.$el.toggleClass('is_selected', this.isSelected());
|
|
951
989
|
},
|
|
952
|
-
isSelected: function
|
|
990
|
+
isSelected: function () {
|
|
953
991
|
return this.options.selection && this.options.selection.get(this.selectionAttribute()) === this.model;
|
|
954
992
|
},
|
|
955
|
-
selectionAttribute: function
|
|
993
|
+
selectionAttribute: function () {
|
|
956
994
|
return this.options.selectionAttribute || 'current';
|
|
957
995
|
}
|
|
958
996
|
});
|
|
@@ -973,7 +1011,7 @@ __p += '<td colspan="' +
|
|
|
973
1011
|
return __p
|
|
974
1012
|
}
|
|
975
1013
|
|
|
976
|
-
|
|
1014
|
+
const TableView = Marionette.ItemView.extend({
|
|
977
1015
|
tagName: 'table',
|
|
978
1016
|
className: 'table_view',
|
|
979
1017
|
template: template$2,
|
|
@@ -981,16 +1019,14 @@ var TableView = Marionette.ItemView.extend({
|
|
|
981
1019
|
headRow: 'thead tr',
|
|
982
1020
|
body: 'tbody'
|
|
983
1021
|
},
|
|
984
|
-
onRender: function
|
|
1022
|
+
onRender: function () {
|
|
985
1023
|
var view = this;
|
|
986
|
-
|
|
987
1024
|
_(this.options.columns).each(function (column) {
|
|
988
1025
|
this.ui.headRow.append(this.subview(new TableHeaderCellView({
|
|
989
1026
|
column: column,
|
|
990
1027
|
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
|
|
991
1028
|
})).el);
|
|
992
1029
|
}, this);
|
|
993
|
-
|
|
994
1030
|
this.subview(new CollectionView({
|
|
995
1031
|
el: this.ui.body,
|
|
996
1032
|
collection: this.collection,
|
|
@@ -1005,7 +1041,7 @@ var TableView = Marionette.ItemView.extend({
|
|
|
1005
1041
|
tagName: 'tr',
|
|
1006
1042
|
className: 'blank_slate',
|
|
1007
1043
|
template: blankSlateTemplate,
|
|
1008
|
-
serializeData: function
|
|
1044
|
+
serializeData: function () {
|
|
1009
1045
|
return {
|
|
1010
1046
|
blankSlateText: view.options.blankSlateText,
|
|
1011
1047
|
colSpan: view.options.columns.length
|
|
@@ -1022,18 +1058,18 @@ __p += '<span class="label">\n</span>\n';
|
|
|
1022
1058
|
return __p
|
|
1023
1059
|
}
|
|
1024
1060
|
|
|
1025
|
-
|
|
1061
|
+
const TooltipView = Marionette.ItemView.extend({
|
|
1026
1062
|
template: template$3,
|
|
1027
1063
|
className: 'tooltip',
|
|
1028
1064
|
ui: {
|
|
1029
1065
|
label: '.label'
|
|
1030
1066
|
},
|
|
1031
|
-
hide: function
|
|
1067
|
+
hide: function () {
|
|
1032
1068
|
this.visible = false;
|
|
1033
1069
|
clearTimeout(this.timeout);
|
|
1034
1070
|
this.$el.removeClass('visible');
|
|
1035
1071
|
},
|
|
1036
|
-
show: function
|
|
1072
|
+
show: function (text, position, options) {
|
|
1037
1073
|
options = options || {};
|
|
1038
1074
|
this.visible = true;
|
|
1039
1075
|
clearTimeout(this.timeout);
|
|
@@ -1044,7 +1080,6 @@ var TooltipView = Marionette.ItemView.extend({
|
|
|
1044
1080
|
this.$el.toggleClass('align_bottom_right', options.align === 'bottom right');
|
|
1045
1081
|
this.$el.toggleClass('align_bottom_left', options.align === 'bottom left');
|
|
1046
1082
|
this.$el.toggleClass('align_top_center', options.align === 'top center');
|
|
1047
|
-
|
|
1048
1083
|
if (options.align === 'bottom right' || options.align === 'bottom left') {
|
|
1049
1084
|
offsetTop = 10;
|
|
1050
1085
|
offsetLeft = 0;
|
|
@@ -1055,7 +1090,6 @@ var TooltipView = Marionette.ItemView.extend({
|
|
|
1055
1090
|
offsetTop = -17;
|
|
1056
1091
|
offsetLeft = 10;
|
|
1057
1092
|
}
|
|
1058
|
-
|
|
1059
1093
|
this.$el.css({
|
|
1060
1094
|
top: position.top + offsetTop + 'px',
|
|
1061
1095
|
left: position.left + offsetLeft + 'px'
|
|
@@ -1065,104 +1099,36 @@ var TooltipView = Marionette.ItemView.extend({
|
|
|
1065
1099
|
}
|
|
1066
1100
|
});
|
|
1067
1101
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
Object.defineProperty(obj, key, {
|
|
1071
|
-
value: value,
|
|
1072
|
-
enumerable: true,
|
|
1073
|
-
configurable: true,
|
|
1074
|
-
writable: true
|
|
1075
|
-
});
|
|
1076
|
-
} else {
|
|
1077
|
-
obj[key] = value;
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
return obj;
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
function ownKeys(object, enumerableOnly) {
|
|
1084
|
-
var keys = Object.keys(object);
|
|
1085
|
-
|
|
1086
|
-
if (Object.getOwnPropertySymbols) {
|
|
1087
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
1088
|
-
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
|
1089
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
1090
|
-
});
|
|
1091
|
-
keys.push.apply(keys, symbols);
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
return keys;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
function _objectSpread2(target) {
|
|
1098
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1099
|
-
var source = arguments[i] != null ? arguments[i] : {};
|
|
1100
|
-
|
|
1101
|
-
if (i % 2) {
|
|
1102
|
-
ownKeys(Object(source), true).forEach(function (key) {
|
|
1103
|
-
_defineProperty(target, key, source[key]);
|
|
1104
|
-
});
|
|
1105
|
-
} else if (Object.getOwnPropertyDescriptors) {
|
|
1106
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
1107
|
-
} else {
|
|
1108
|
-
ownKeys(Object(source)).forEach(function (key) {
|
|
1109
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
1110
|
-
});
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1114
|
-
return target;
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
var attributeBinding = {
|
|
1118
|
-
setupBooleanAttributeBinding: function setupBooleanAttributeBinding(optionName, updateMethod) {
|
|
1102
|
+
const attributeBinding = {
|
|
1103
|
+
setupBooleanAttributeBinding(optionName, updateMethod) {
|
|
1119
1104
|
this.setupAttributeBinding(optionName, updateMethod, Boolean);
|
|
1120
1105
|
},
|
|
1121
|
-
getBooleanAttributBoundOption
|
|
1106
|
+
getBooleanAttributBoundOption(optionName) {
|
|
1122
1107
|
return this.getAttributeBoundOption(optionName, Boolean);
|
|
1123
1108
|
},
|
|
1124
|
-
setupAttributeBinding
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
});
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
update();
|
|
1140
|
-
|
|
1141
|
-
function update() {
|
|
1142
|
-
updateMethod.call(view, view.getAttributeBoundOption(optionName, normalize));
|
|
1143
|
-
}
|
|
1109
|
+
setupAttributeBinding(optionName, updateMethod, normalize = value => value) {
|
|
1110
|
+
const binding = this.options[`${optionName}Binding`];
|
|
1111
|
+
const model = this.options[`${optionName}BindingModel`] || this.model;
|
|
1112
|
+
setup({
|
|
1113
|
+
binding,
|
|
1114
|
+
model,
|
|
1115
|
+
listener: this,
|
|
1116
|
+
normalize,
|
|
1117
|
+
option: this.options[optionName],
|
|
1118
|
+
bindingValue: this.options[`${optionName}BindingValue`],
|
|
1119
|
+
callback: value => updateMethod.call(this, value)
|
|
1120
|
+
});
|
|
1144
1121
|
},
|
|
1145
|
-
getAttributeBoundOption
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
}) : this.model.get(binding);
|
|
1156
|
-
|
|
1157
|
-
if (bindingValueOptionName in this.options) {
|
|
1158
|
-
return value === this.options[bindingValueOptionName];
|
|
1159
|
-
} else if (typeof this.options[optionName] === 'function') {
|
|
1160
|
-
return normalize(this.options[optionName](value));
|
|
1161
|
-
} else if (optionName in this.options) {
|
|
1162
|
-
return normalize(this.options[optionName]);
|
|
1163
|
-
} else if (binding) {
|
|
1164
|
-
return normalize(value);
|
|
1165
|
-
}
|
|
1122
|
+
getAttributeBoundOption(optionName, normalize = value => value) {
|
|
1123
|
+
const binding = this.options[`${optionName}Binding`];
|
|
1124
|
+
const model = this.options[`${optionName}BindingModel`] || this.model;
|
|
1125
|
+
return resolve({
|
|
1126
|
+
binding,
|
|
1127
|
+
model,
|
|
1128
|
+
normalize,
|
|
1129
|
+
option: this.options[optionName],
|
|
1130
|
+
bindingValue: this.options[`${optionName}BindingValue`]
|
|
1131
|
+
});
|
|
1166
1132
|
}
|
|
1167
1133
|
};
|
|
1168
1134
|
|
|
@@ -1255,6 +1221,11 @@ var attributeBinding = {
|
|
|
1255
1221
|
* An array of prefixes to lookup translations for labels and
|
|
1256
1222
|
* inline help texts based on attribute names.
|
|
1257
1223
|
*
|
|
1224
|
+
* @param {string} [options.attributeTranslationPropertyName]
|
|
1225
|
+
* Use this property name instead of `propertyName` for looking up
|
|
1226
|
+
* translations. Useful when the property name has been transformed
|
|
1227
|
+
* but translations should use the original name.
|
|
1228
|
+
*
|
|
1258
1229
|
* @param {string} [options.additionalInlineHelpText]
|
|
1259
1230
|
* A text that will be appended to the translation based inline
|
|
1260
1231
|
* text.
|
|
@@ -1276,6 +1247,9 @@ var attributeBinding = {
|
|
|
1276
1247
|
* Input will be disabled whenever the value of the `disabledBinding`
|
|
1277
1248
|
* attribute equals the value of this option.
|
|
1278
1249
|
*
|
|
1250
|
+
* @param {Backbone.Model} [options.disabledBindingModel]
|
|
1251
|
+
* Alternative model to bind to.
|
|
1252
|
+
*
|
|
1279
1253
|
* @param {string|string[]} [options.visibleBinding]
|
|
1280
1254
|
* Name of an attribute to control whether the input is visible. If
|
|
1281
1255
|
* the `visible` and `visibleBindingValue` options are not set,
|
|
@@ -1292,16 +1266,18 @@ var attributeBinding = {
|
|
|
1292
1266
|
* Input will be visible whenever the value of the `visibleBinding`
|
|
1293
1267
|
* attribute equals the value of this option.
|
|
1294
1268
|
*
|
|
1269
|
+
* @param {Backbone.Model} [options.visibleBindingModel]
|
|
1270
|
+
* Alternative model to bind to.
|
|
1271
|
+
*
|
|
1295
1272
|
* @mixin
|
|
1296
1273
|
*/
|
|
1297
|
-
|
|
1298
|
-
|
|
1274
|
+
const inputView = {
|
|
1275
|
+
...attributeBinding,
|
|
1299
1276
|
ui: {
|
|
1300
1277
|
label: 'label',
|
|
1301
1278
|
labelText: 'label .name',
|
|
1302
1279
|
inlineHelp: 'label .inline_help'
|
|
1303
1280
|
},
|
|
1304
|
-
|
|
1305
1281
|
/**
|
|
1306
1282
|
* Returns an array of translation keys based on the
|
|
1307
1283
|
* `attributeTranslationKeyPrefixes` option and the given keyName.
|
|
@@ -1324,92 +1300,89 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
|
|
|
1324
1300
|
* @since 0.9
|
|
1325
1301
|
* @member
|
|
1326
1302
|
*/
|
|
1327
|
-
attributeTranslationKeys: function
|
|
1328
|
-
return attributeTranslationKeys(this.options.propertyName, keyName, _.extend({
|
|
1303
|
+
attributeTranslationKeys: function (keyName, options) {
|
|
1304
|
+
return attributeTranslationKeys(this.options.attributeTranslationPropertyName || this.options.propertyName, keyName, _.extend({
|
|
1329
1305
|
prefixes: this.options.attributeTranslationKeyPrefixes,
|
|
1330
1306
|
fallbackModelI18nKey: this.model.i18nKey
|
|
1331
1307
|
}, options || {}));
|
|
1332
1308
|
},
|
|
1333
|
-
onRender: function
|
|
1309
|
+
onRender: function () {
|
|
1334
1310
|
this.$el.addClass('input');
|
|
1335
1311
|
this.$el.addClass(this.model.modelName + '_' + this.options.propertyName);
|
|
1336
1312
|
this.$el.data('inputPropertyName', this.options.propertyName);
|
|
1337
1313
|
this.$el.data('labelText', this.labelText());
|
|
1338
1314
|
this.$el.data('inlineHelpText', this.inlineHelpText());
|
|
1339
1315
|
this.ui.labelText.text(this.labelText());
|
|
1316
|
+
if (this.options.hideLabel) {
|
|
1317
|
+
this.ui.label.addClass('visually_hidden');
|
|
1318
|
+
}
|
|
1340
1319
|
this.updateInlineHelp();
|
|
1341
1320
|
this.setLabelFor();
|
|
1342
1321
|
this.setupBooleanAttributeBinding('disabled', this.updateDisabled);
|
|
1343
1322
|
this.setupBooleanAttributeBinding('visible', this.updateVisible);
|
|
1344
1323
|
},
|
|
1345
|
-
|
|
1346
1324
|
/**
|
|
1347
1325
|
* The label to display in the form.
|
|
1348
1326
|
* @return {string}
|
|
1349
1327
|
*/
|
|
1350
|
-
labelText: function
|
|
1328
|
+
labelText: function () {
|
|
1351
1329
|
return this.options.label || this.localizedAttributeName();
|
|
1352
1330
|
},
|
|
1353
|
-
localizedAttributeName: function
|
|
1331
|
+
localizedAttributeName: function () {
|
|
1354
1332
|
return findTranslation(this.attributeTranslationKeys('label', {
|
|
1355
1333
|
fallbackPrefix: 'activerecord.attributes'
|
|
1356
1334
|
}));
|
|
1357
1335
|
},
|
|
1358
|
-
updateInlineHelp: function
|
|
1336
|
+
updateInlineHelp: function () {
|
|
1359
1337
|
this.ui.inlineHelp.html(this.inlineHelpText());
|
|
1360
|
-
|
|
1361
1338
|
if (!this.inlineHelpText()) {
|
|
1362
1339
|
this.ui.inlineHelp.hide();
|
|
1363
1340
|
}
|
|
1364
1341
|
},
|
|
1365
|
-
|
|
1366
1342
|
/**
|
|
1367
1343
|
* The inline help text for the form field.
|
|
1368
1344
|
* @return {string}
|
|
1369
1345
|
*/
|
|
1370
|
-
inlineHelpText: function
|
|
1346
|
+
inlineHelpText: function () {
|
|
1371
1347
|
var keys = this.attributeTranslationKeys('inline_help', {
|
|
1372
1348
|
fallbackPrefix: 'pageflow.ui.inline_help'
|
|
1373
1349
|
});
|
|
1374
|
-
|
|
1375
1350
|
if (this.isDisabled()) {
|
|
1376
1351
|
keys = translationKeysWithSuffix(keys, 'disabled');
|
|
1377
1352
|
}
|
|
1378
|
-
|
|
1379
1353
|
return _.compact([findTranslation(keys, {
|
|
1380
1354
|
defaultValue: '',
|
|
1381
1355
|
html: true
|
|
1382
1356
|
}), this.options.additionalInlineHelpText]).join(' ');
|
|
1383
1357
|
},
|
|
1384
|
-
setLabelFor
|
|
1358
|
+
setLabelFor() {
|
|
1385
1359
|
if (this.ui.input && this.ui.label.length === 1 && !this.ui.input.attr('id')) {
|
|
1386
|
-
|
|
1360
|
+
const id = 'input_' + this.model.modelName + '_' + this.options.propertyName;
|
|
1387
1361
|
this.ui.input.attr('id', id);
|
|
1388
1362
|
this.ui.label.attr('for', id);
|
|
1389
1363
|
}
|
|
1390
1364
|
},
|
|
1391
|
-
isDisabled: function
|
|
1365
|
+
isDisabled: function () {
|
|
1392
1366
|
return this.getBooleanAttributBoundOption('disabled');
|
|
1393
1367
|
},
|
|
1394
|
-
updateDisabled: function
|
|
1368
|
+
updateDisabled: function () {
|
|
1395
1369
|
this.$el.toggleClass('input-disabled', !!this.isDisabled());
|
|
1396
1370
|
this.updateInlineHelp();
|
|
1397
|
-
|
|
1398
1371
|
if (this.ui.input) {
|
|
1399
1372
|
this.updateDisabledAttribute(this.ui.input);
|
|
1400
1373
|
}
|
|
1401
1374
|
},
|
|
1402
|
-
updateDisabledAttribute: function
|
|
1375
|
+
updateDisabledAttribute: function (element) {
|
|
1403
1376
|
if (this.isDisabled()) {
|
|
1404
1377
|
element.attr('disabled', true);
|
|
1405
1378
|
} else {
|
|
1406
1379
|
element.removeAttr('disabled');
|
|
1407
1380
|
}
|
|
1408
1381
|
},
|
|
1409
|
-
updateVisible: function
|
|
1382
|
+
updateVisible: function () {
|
|
1410
1383
|
this.$el.toggleClass('hidden_via_binding', this.getBooleanAttributBoundOption('visible') === false);
|
|
1411
1384
|
}
|
|
1412
|
-
}
|
|
1385
|
+
};
|
|
1413
1386
|
|
|
1414
1387
|
function template$4(data) {
|
|
1415
1388
|
var __p = '';
|
|
@@ -1425,8 +1398,7 @@ return __p
|
|
|
1425
1398
|
*
|
|
1426
1399
|
* @class
|
|
1427
1400
|
*/
|
|
1428
|
-
|
|
1429
|
-
var CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
1401
|
+
const CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
1430
1402
|
mixins: [inputView],
|
|
1431
1403
|
template: template$4,
|
|
1432
1404
|
className: 'check_box_group_input',
|
|
@@ -1437,7 +1409,7 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
|
1437
1409
|
label: 'label',
|
|
1438
1410
|
container: '.check_boxes_container'
|
|
1439
1411
|
},
|
|
1440
|
-
initialize: function
|
|
1412
|
+
initialize: function () {
|
|
1441
1413
|
if (!this.options.texts) {
|
|
1442
1414
|
if (!this.options.translationKeys) {
|
|
1443
1415
|
var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
|
|
@@ -1447,34 +1419,31 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
|
1447
1419
|
return translationKeyPrefix + '.' + value;
|
|
1448
1420
|
}, this);
|
|
1449
1421
|
}
|
|
1450
|
-
|
|
1451
1422
|
this.options.texts = _.map(this.options.translationKeys, function (key) {
|
|
1452
1423
|
return I18n$1.t(key);
|
|
1453
1424
|
});
|
|
1454
1425
|
}
|
|
1455
1426
|
},
|
|
1456
|
-
onRender: function
|
|
1427
|
+
onRender: function () {
|
|
1457
1428
|
this.ui.label.attr('for', this.cid);
|
|
1458
1429
|
this.appendOptions();
|
|
1459
1430
|
this.load();
|
|
1460
1431
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1461
1432
|
},
|
|
1462
|
-
appendOptions: function
|
|
1433
|
+
appendOptions: function () {
|
|
1463
1434
|
_.each(this.options.values, function (value, index) {
|
|
1464
1435
|
var option = '<div class="check_box">' + '<label><input type="checkbox" name="' + value + '" />' + this.options.texts[index] + '</label></div>';
|
|
1465
1436
|
this.ui.container.append($(option));
|
|
1466
1437
|
}, this);
|
|
1467
1438
|
},
|
|
1468
|
-
save: function
|
|
1439
|
+
save: function () {
|
|
1469
1440
|
var configured = {};
|
|
1470
|
-
|
|
1471
1441
|
_.each(this.ui.container.find('input'), function (input) {
|
|
1472
1442
|
configured[$(input).attr('name')] = $(input).prop('checked');
|
|
1473
1443
|
});
|
|
1474
|
-
|
|
1475
1444
|
this.model.set(this.options.propertyName, configured);
|
|
1476
1445
|
},
|
|
1477
|
-
load: function
|
|
1446
|
+
load: function () {
|
|
1478
1447
|
if (!this.isClosed) {
|
|
1479
1448
|
_.each(this.options.values, function (value) {
|
|
1480
1449
|
this.ui.container.find('input[name="' + value + '"]').prop('checked', this.model.get(this.options.propertyName)[value]);
|
|
@@ -1502,8 +1471,7 @@ return __p
|
|
|
1502
1471
|
*
|
|
1503
1472
|
* @class
|
|
1504
1473
|
*/
|
|
1505
|
-
|
|
1506
|
-
var UrlDisplayView = Marionette.ItemView.extend({
|
|
1474
|
+
const UrlDisplayView = Marionette.ItemView.extend({
|
|
1507
1475
|
mixins: [inputView],
|
|
1508
1476
|
template: template$5,
|
|
1509
1477
|
ui: {
|
|
@@ -1513,43 +1481,21 @@ var UrlDisplayView = Marionette.ItemView.extend({
|
|
|
1513
1481
|
'change': 'update'
|
|
1514
1482
|
},
|
|
1515
1483
|
events: {
|
|
1516
|
-
'click a': function
|
|
1484
|
+
'click a': function (event) {
|
|
1517
1485
|
// Ensure default is not prevented by parent event listener.
|
|
1518
1486
|
event.stopPropagation();
|
|
1519
1487
|
}
|
|
1520
1488
|
},
|
|
1521
|
-
onRender: function
|
|
1489
|
+
onRender: function () {
|
|
1522
1490
|
this.update();
|
|
1523
1491
|
},
|
|
1524
|
-
update: function
|
|
1525
|
-
var url = this.model.get('original_url');
|
|
1492
|
+
update: function () {
|
|
1493
|
+
var url = this.model.get(this.options.propertyName || 'original_url');
|
|
1526
1494
|
this.$el.toggle(this.model.isUploaded() && !_.isEmpty(url));
|
|
1527
1495
|
this.ui.link.attr('href', url);
|
|
1528
1496
|
}
|
|
1529
1497
|
});
|
|
1530
1498
|
|
|
1531
|
-
function _classCallCheck(instance, Constructor) {
|
|
1532
|
-
if (!(instance instanceof Constructor)) {
|
|
1533
|
-
throw new TypeError("Cannot call a class as a function");
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
|
|
1537
|
-
function _defineProperties(target, props) {
|
|
1538
|
-
for (var i = 0; i < props.length; i++) {
|
|
1539
|
-
var descriptor = props[i];
|
|
1540
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
|
1541
|
-
descriptor.configurable = true;
|
|
1542
|
-
if ("value" in descriptor) descriptor.writable = true;
|
|
1543
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
|
1544
|
-
}
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
|
1548
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
1549
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
1550
|
-
return Constructor;
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
1499
|
/**
|
|
1554
1500
|
* Input view for a number.
|
|
1555
1501
|
*
|
|
@@ -1562,90 +1508,73 @@ function _createClass(Constructor, protoProps, staticProps) {
|
|
|
1562
1508
|
*
|
|
1563
1509
|
* @class
|
|
1564
1510
|
*/
|
|
1565
|
-
|
|
1566
|
-
var NumberInputView = Marionette.ItemView.extend({
|
|
1511
|
+
const NumberInputView = Marionette.ItemView.extend({
|
|
1567
1512
|
mixins: [inputView],
|
|
1568
|
-
template:
|
|
1569
|
-
|
|
1570
|
-
|
|
1513
|
+
template: () => `
|
|
1514
|
+
<label>
|
|
1515
|
+
<span class="name"></span>
|
|
1516
|
+
<span class="inline_help"></span>
|
|
1517
|
+
</label>
|
|
1518
|
+
<input type="text" dir="auto" />
|
|
1519
|
+
`,
|
|
1571
1520
|
ui: {
|
|
1572
1521
|
input: 'input'
|
|
1573
1522
|
},
|
|
1574
1523
|
events: {
|
|
1575
1524
|
'change': 'onChange'
|
|
1576
1525
|
},
|
|
1577
|
-
initialize
|
|
1526
|
+
initialize() {
|
|
1578
1527
|
this.parser = new NumberParser(this.options.locale);
|
|
1579
1528
|
},
|
|
1580
|
-
onRender: function
|
|
1529
|
+
onRender: function () {
|
|
1581
1530
|
this.load();
|
|
1582
1531
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1583
1532
|
},
|
|
1584
|
-
onChange: function
|
|
1533
|
+
onChange: function () {
|
|
1585
1534
|
this.save();
|
|
1586
1535
|
this.load();
|
|
1587
1536
|
},
|
|
1588
|
-
onClose: function
|
|
1537
|
+
onClose: function () {
|
|
1589
1538
|
this.save();
|
|
1590
1539
|
},
|
|
1591
|
-
save: function
|
|
1592
|
-
|
|
1540
|
+
save: function () {
|
|
1541
|
+
const inputValue = this.ui.input.val();
|
|
1593
1542
|
this.model.set(this.options.propertyName, this.parser.parse(inputValue) || 0);
|
|
1594
1543
|
},
|
|
1595
|
-
load: function
|
|
1596
|
-
|
|
1597
|
-
|
|
1544
|
+
load: function () {
|
|
1545
|
+
const input = this.ui.input;
|
|
1546
|
+
const value = this.model.get(this.options.propertyName) || 0;
|
|
1598
1547
|
input.val(value.toLocaleString(this.options.locale, {
|
|
1599
1548
|
useGrouping: false
|
|
1600
1549
|
}));
|
|
1601
1550
|
},
|
|
1602
|
-
displayValidationError: function
|
|
1551
|
+
displayValidationError: function (message) {
|
|
1603
1552
|
this.$el.addClass('invalid');
|
|
1604
1553
|
this.ui.input.attr('title', message);
|
|
1605
1554
|
},
|
|
1606
|
-
resetValidationError: function
|
|
1555
|
+
resetValidationError: function (message) {
|
|
1607
1556
|
this.$el.removeClass('invalid');
|
|
1608
1557
|
this.ui.input.attr('title', '');
|
|
1609
1558
|
}
|
|
1610
1559
|
});
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
var format = new Intl.NumberFormat(locale);
|
|
1617
|
-
var parts = format.formatToParts(12345.6);
|
|
1618
|
-
var numerals = Array.from({
|
|
1560
|
+
class NumberParser {
|
|
1561
|
+
constructor(locale) {
|
|
1562
|
+
const format = new Intl.NumberFormat(locale);
|
|
1563
|
+
const parts = format.formatToParts(12345.6);
|
|
1564
|
+
const numerals = Array.from({
|
|
1619
1565
|
length: 10
|
|
1620
|
-
}).map(
|
|
1621
|
-
|
|
1622
|
-
});
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
this._group = new RegExp("[".concat(parts.find(function (d) {
|
|
1627
|
-
return d.type === "group";
|
|
1628
|
-
}).value, "]"), "g");
|
|
1629
|
-
this._decimal = new RegExp("[".concat(parts.find(function (d) {
|
|
1630
|
-
return d.type === "decimal";
|
|
1631
|
-
}).value, "]"));
|
|
1632
|
-
this._numeral = new RegExp("[".concat(numerals.join(""), "]"), "g");
|
|
1633
|
-
|
|
1634
|
-
this._index = function (d) {
|
|
1635
|
-
return index.get(d);
|
|
1636
|
-
};
|
|
1566
|
+
}).map((_, i) => format.format(i));
|
|
1567
|
+
const index = new Map(numerals.map((d, i) => [d, i]));
|
|
1568
|
+
this._group = new RegExp(`[${parts.find(d => d.type === "group").value}]`, "g");
|
|
1569
|
+
this._decimal = new RegExp(`[${parts.find(d => d.type === "decimal").value}]`);
|
|
1570
|
+
this._numeral = new RegExp(`[${numerals.join("")}]`, "g");
|
|
1571
|
+
this._index = d => index.get(d);
|
|
1637
1572
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
return string ? +string : NaN;
|
|
1644
|
-
}
|
|
1645
|
-
}]);
|
|
1646
|
-
|
|
1647
|
-
return NumberParser;
|
|
1648
|
-
}();
|
|
1573
|
+
parse(string) {
|
|
1574
|
+
string = string.trim().replace(this._group, "").replace(this._decimal, ".").replace(this._numeral, this._index);
|
|
1575
|
+
return string ? +string : NaN;
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1649
1578
|
|
|
1650
1579
|
/**
|
|
1651
1580
|
* Text based input view that can display a placeholder.
|
|
@@ -1668,21 +1597,20 @@ var NumberParser = /*#__PURE__*/function () {
|
|
|
1668
1597
|
* Obtain placeholder by looking up the configured `propertyName`
|
|
1669
1598
|
* inside a given model.
|
|
1670
1599
|
*/
|
|
1671
|
-
|
|
1672
|
-
onRender: function
|
|
1600
|
+
const inputWithPlaceholderText = {
|
|
1601
|
+
onRender: function () {
|
|
1673
1602
|
this.updatePlaceholder();
|
|
1674
|
-
|
|
1675
1603
|
if (this.options.placeholderBinding) {
|
|
1676
1604
|
this.listenTo(this.model, 'change:' + this.options.placeholderBinding, this.updatePlaceholder);
|
|
1677
1605
|
}
|
|
1678
1606
|
},
|
|
1679
|
-
updateDisabled: function
|
|
1607
|
+
updateDisabled: function () {
|
|
1680
1608
|
this.updatePlaceholder();
|
|
1681
1609
|
},
|
|
1682
|
-
updatePlaceholder: function
|
|
1610
|
+
updatePlaceholder: function () {
|
|
1683
1611
|
this.ui.input.attr('placeholder', this.placeholderText());
|
|
1684
1612
|
},
|
|
1685
|
-
placeholderText: function
|
|
1613
|
+
placeholderText: function () {
|
|
1686
1614
|
if (!this.isDisabled() || !this.options.hidePlaceholderIfDisabled) {
|
|
1687
1615
|
if (this.options.placeholder) {
|
|
1688
1616
|
if (typeof this.options.placeholder == 'function') {
|
|
@@ -1694,30 +1622,24 @@ var inputWithPlaceholderText = {
|
|
|
1694
1622
|
return this.placeholderModelValue();
|
|
1695
1623
|
}
|
|
1696
1624
|
}
|
|
1697
|
-
|
|
1698
1625
|
return '';
|
|
1699
1626
|
},
|
|
1700
|
-
placeholderModelValue: function
|
|
1627
|
+
placeholderModelValue: function () {
|
|
1701
1628
|
return this.options.placeholderModel && this.options.placeholderModel.get(this.options.propertyName);
|
|
1702
1629
|
}
|
|
1703
1630
|
};
|
|
1704
1631
|
|
|
1705
|
-
|
|
1706
|
-
onRender
|
|
1632
|
+
const viewWithValidationErrorMessages = {
|
|
1633
|
+
onRender() {
|
|
1707
1634
|
this.listenTo(this.model, 'invalid sync', this.updateValidationErrorMessages);
|
|
1708
1635
|
this.updateValidationErrorMessages();
|
|
1709
1636
|
},
|
|
1710
|
-
updateValidationErrorMessages
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
var errors = this.model.validationErrors && this.model.validationErrors[this.options.propertyName] || [];
|
|
1714
|
-
|
|
1637
|
+
updateValidationErrorMessages() {
|
|
1638
|
+
const errors = this.model.validationErrors && this.model.validationErrors[this.options.propertyName] || [];
|
|
1715
1639
|
if (errors.length) {
|
|
1716
1640
|
this.validationErrorList = this.validationErrorList || $('<ul class="validation_error_messages" />').appendTo(this.el);
|
|
1717
1641
|
this.validationErrorList.html('');
|
|
1718
|
-
errors.forEach(
|
|
1719
|
-
return _this.validationErrorList.append("<li>".concat(error, "</li>"));
|
|
1720
|
-
});
|
|
1642
|
+
errors.forEach(error => this.validationErrorList.append(`<li>${error}</li>`));
|
|
1721
1643
|
this.$el.addClass('invalid');
|
|
1722
1644
|
} else if (this.validationErrorList) {
|
|
1723
1645
|
this.validationErrorList.remove();
|
|
@@ -1752,8 +1674,7 @@ return __p
|
|
|
1752
1674
|
*
|
|
1753
1675
|
* @class
|
|
1754
1676
|
*/
|
|
1755
|
-
|
|
1756
|
-
var TextInputView = Marionette.ItemView.extend({
|
|
1677
|
+
const TextInputView = Marionette.ItemView.extend({
|
|
1757
1678
|
mixins: [inputView, inputWithPlaceholderText, viewWithValidationErrorMessages],
|
|
1758
1679
|
template: template$6,
|
|
1759
1680
|
ui: {
|
|
@@ -1762,41 +1683,40 @@ var TextInputView = Marionette.ItemView.extend({
|
|
|
1762
1683
|
events: {
|
|
1763
1684
|
'change': 'onChange'
|
|
1764
1685
|
},
|
|
1765
|
-
onRender: function
|
|
1686
|
+
onRender: function () {
|
|
1766
1687
|
this.load();
|
|
1767
1688
|
this.validate();
|
|
1768
1689
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1769
1690
|
},
|
|
1770
|
-
onChange: function
|
|
1691
|
+
onChange: function () {
|
|
1771
1692
|
if (this.validate()) {
|
|
1772
1693
|
this.save();
|
|
1773
1694
|
}
|
|
1774
1695
|
},
|
|
1775
|
-
onClose: function
|
|
1696
|
+
onClose: function () {
|
|
1776
1697
|
if (this.validate()) {
|
|
1777
1698
|
this.save();
|
|
1778
1699
|
}
|
|
1779
1700
|
},
|
|
1780
|
-
save: function
|
|
1701
|
+
save: function () {
|
|
1781
1702
|
this.model.set(this.options.propertyName, this.ui.input.val());
|
|
1782
1703
|
},
|
|
1783
|
-
load: function
|
|
1704
|
+
load: function () {
|
|
1784
1705
|
var input = this.ui.input;
|
|
1785
|
-
input.val(this.model.get(this.options.propertyName));
|
|
1706
|
+
input.val(this.model.get(this.options.propertyName));
|
|
1786
1707
|
|
|
1787
|
-
|
|
1708
|
+
// set mysql varchar length as default for non-legacy data
|
|
1709
|
+
this.options.maxLength = this.options.maxLength || 255;
|
|
1710
|
+
// do not validate legacy data which length exceeds the specified maximum
|
|
1788
1711
|
// for new and maxLength-conforming data: add validation
|
|
1789
|
-
|
|
1790
1712
|
this.validateMaxLength = input.val().length <= this.options.maxLength;
|
|
1791
1713
|
},
|
|
1792
|
-
validate: function
|
|
1714
|
+
validate: function () {
|
|
1793
1715
|
var input = this.ui.input;
|
|
1794
|
-
|
|
1795
1716
|
if (this.options.required && !input.val()) {
|
|
1796
1717
|
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.required_field'));
|
|
1797
1718
|
return false;
|
|
1798
1719
|
}
|
|
1799
|
-
|
|
1800
1720
|
if (this.validateMaxLength && input.val().length > this.options.maxLength) {
|
|
1801
1721
|
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.max_characters_exceeded', {
|
|
1802
1722
|
max_length: this.options.maxLength
|
|
@@ -1807,112 +1727,763 @@ var TextInputView = Marionette.ItemView.extend({
|
|
|
1807
1727
|
return true;
|
|
1808
1728
|
}
|
|
1809
1729
|
},
|
|
1810
|
-
displayValidationError: function
|
|
1730
|
+
displayValidationError: function (message) {
|
|
1811
1731
|
this.$el.addClass('invalid');
|
|
1812
1732
|
this.ui.input.attr('title', message);
|
|
1813
1733
|
},
|
|
1814
|
-
resetValidationError: function
|
|
1734
|
+
resetValidationError: function (message) {
|
|
1815
1735
|
this.$el.removeClass('invalid');
|
|
1816
1736
|
this.ui.input.attr('title', '');
|
|
1817
1737
|
}
|
|
1818
1738
|
});
|
|
1819
1739
|
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
*
|
|
1826
|
-
* @param {string|function} [options.defaultValue]
|
|
1827
|
-
* Color value to display by default. The corresponding value is not
|
|
1828
|
-
* stored in the model. Selecting the default value when a different
|
|
1829
|
-
* value was set before, unsets the attribute in the model.
|
|
1830
|
-
*
|
|
1831
|
-
* @param {string} [options.defaultValueBinding]
|
|
1832
|
-
* Name of an attribute the default value depends on. If a function
|
|
1833
|
-
* is used as defaultValue option, it will be passed the value of the
|
|
1834
|
-
* defaultValueBinding attribute each time it changes. If no
|
|
1835
|
-
* defaultValue option is set, the value of the defaultValueBinding
|
|
1836
|
-
* attribute will be used as default value.
|
|
1837
|
-
*
|
|
1838
|
-
* @param {string[]} [options.swatches]
|
|
1839
|
-
* Preset color values to be displayed inside the picker drop
|
|
1840
|
-
* down. The default value, if present, is always used as the
|
|
1841
|
-
* first swatch automatically.
|
|
1842
|
-
*
|
|
1843
|
-
* @class
|
|
1844
|
-
*/
|
|
1740
|
+
function template$7(data) {
|
|
1741
|
+
var __p = '';
|
|
1742
|
+
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="file_name_input-wrapper">\n <input type="text" dir="auto" />\n <span class="file_name_input-extension"></span>\n</div>\n';
|
|
1743
|
+
return __p
|
|
1744
|
+
}
|
|
1845
1745
|
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
this.ui.
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1746
|
+
const FileNameInputView = TextInputView.extend({
|
|
1747
|
+
template: template$7,
|
|
1748
|
+
className: 'file_name_input',
|
|
1749
|
+
ui: Object.assign({}, TextInputView.prototype.ui, {
|
|
1750
|
+
extension: '.file_name_input-extension'
|
|
1751
|
+
}),
|
|
1752
|
+
onRender: function () {
|
|
1753
|
+
TextInputView.prototype.onRender.call(this);
|
|
1754
|
+
},
|
|
1755
|
+
save: function () {
|
|
1756
|
+
const baseName = this.ui.input.val();
|
|
1757
|
+
const extension = this.ui.extension.text();
|
|
1758
|
+
this.model.set(this.options.propertyName, baseName + extension);
|
|
1759
|
+
},
|
|
1760
|
+
load: function () {
|
|
1761
|
+
const fullName = this.model.get(this.options.propertyName) || '';
|
|
1762
|
+
const match = fullName.match(/^(.*?)(\.[^.]+)?$/);
|
|
1763
|
+
const baseName = match ? match[1] : fullName;
|
|
1764
|
+
const extension = match && match[2] ? match[2] : '';
|
|
1765
|
+
this.ui.input.val(baseName);
|
|
1766
|
+
this.ui.extension.text(extension);
|
|
1767
|
+
this.options.maxLength = this.options.maxLength || 255;
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1861
1770
|
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1771
|
+
// Inspired by https://github.com/mdbassit/Coloris
|
|
1772
|
+
const ctx = typeof OffscreenCanvas !== 'undefined' && new OffscreenCanvas(1, 1).getContext('2d');
|
|
1773
|
+
const DEFAULT_DISPLAY_COLOR = {
|
|
1774
|
+
r: 255,
|
|
1775
|
+
g: 255,
|
|
1776
|
+
b: 255,
|
|
1777
|
+
a: 1
|
|
1778
|
+
};
|
|
1779
|
+
let nextDescriptionId = 0;
|
|
1780
|
+
const PICKER_HTML = '<div class="color_picker-gradient" role="application">' + '<div class="color_picker-marker" tabindex="0"></div>' + '</div>' + '<div class="color_picker-hue">' + '<input type="range" min="0" max="360" step="1">' + '<div></div>' + '</div>' + '<div class="color_picker-alpha">' + '<input type="range" min="0" max="100" step="1">' + '<div></div>' + '<span></span>' + '</div>' + '<div class="color_picker-swatches"></div>';
|
|
1781
|
+
class ColorPicker {
|
|
1782
|
+
constructor(input, options = {}) {
|
|
1783
|
+
this._input = input;
|
|
1784
|
+
this._colorAreaDims = {};
|
|
1785
|
+
this._alpha = options.alpha || false;
|
|
1786
|
+
this._onChange = options.onChange;
|
|
1787
|
+
this._defaultColor = strToRGBA(options.defaultValue);
|
|
1788
|
+
this._fallbackColor = strToRGBA(options.fallbackColor);
|
|
1789
|
+
this._fallbackColorDescription = options.fallbackColorDescription;
|
|
1790
|
+
this._swatches = options.swatches || [];
|
|
1791
|
+
this._wrapInput();
|
|
1792
|
+
this._createPicker();
|
|
1793
|
+
this._renderSwatches();
|
|
1794
|
+
this._bindEvents();
|
|
1795
|
+
this._updateColor(strToRGBA(this._input.value), {
|
|
1796
|
+
silent: true
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
setValue(str) {
|
|
1800
|
+
this._input.value = str || '';
|
|
1801
|
+
this._updateColor(strToRGBA(str), {
|
|
1802
|
+
silent: true
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
update(options) {
|
|
1806
|
+
if ('defaultValue' in options) {
|
|
1807
|
+
this._defaultColor = strToRGBA(options.defaultValue);
|
|
1808
|
+
}
|
|
1809
|
+
if ('fallbackColor' in options) {
|
|
1810
|
+
this._fallbackColor = strToRGBA(options.fallbackColor);
|
|
1811
|
+
this._updateColor(this._currentColor, {
|
|
1812
|
+
silent: true
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
if (options.swatches) {
|
|
1816
|
+
this._swatches = options.swatches;
|
|
1817
|
+
this._renderSwatches();
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
destroy() {
|
|
1821
|
+
this._close();
|
|
1822
|
+
this._unbindEvents();
|
|
1823
|
+
this._picker.remove();
|
|
1824
|
+
this._unwrapInput();
|
|
1825
|
+
}
|
|
1867
1826
|
|
|
1868
|
-
|
|
1869
|
-
|
|
1827
|
+
// Setup
|
|
1828
|
+
|
|
1829
|
+
_createPicker() {
|
|
1830
|
+
this._picker = document.createElement('div');
|
|
1831
|
+
this._picker.className = 'color_picker';
|
|
1832
|
+
this._picker.classList.toggle('color_picker-no_alpha', !this._alpha);
|
|
1833
|
+
this._picker.innerHTML = PICKER_HTML;
|
|
1834
|
+
this._input.parentNode.appendChild(this._picker);
|
|
1835
|
+
this._colorArea = this._picker.querySelector('.color_picker-gradient');
|
|
1836
|
+
this._colorMarker = this._picker.querySelector('.color_picker-marker');
|
|
1837
|
+
this._hueSlider = this._picker.querySelector('.color_picker-hue input');
|
|
1838
|
+
this._hueMarker = this._picker.querySelector('.color_picker-hue div');
|
|
1839
|
+
this._alphaSlider = this._picker.querySelector('.color_picker-alpha input');
|
|
1840
|
+
this._alphaMarker = this._picker.querySelector('.color_picker-alpha div');
|
|
1841
|
+
this._swatchesContainer = this._picker.querySelector('.color_picker-swatches');
|
|
1842
|
+
this._hueSlider.setAttribute('aria-label', I18n$1.t('pageflow.ui.color_picker.hue'));
|
|
1843
|
+
if (this._alpha) {
|
|
1844
|
+
this._alphaSlider.setAttribute('aria-label', I18n$1.t('pageflow.ui.color_picker.opacity'));
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
_wrapInput() {
|
|
1848
|
+
const parent = this._input.parentNode;
|
|
1849
|
+
if (!parent.classList.contains('color_picker-field')) {
|
|
1850
|
+
const wrapper = document.createElement('div');
|
|
1851
|
+
wrapper.innerHTML = '<span></span>';
|
|
1852
|
+
parent.insertBefore(wrapper, this._input);
|
|
1853
|
+
wrapper.className = 'color_picker-field';
|
|
1854
|
+
wrapper.appendChild(this._input);
|
|
1855
|
+
if (this._fallbackColorDescription) {
|
|
1856
|
+
this._descriptionElement = document.createElement('span');
|
|
1857
|
+
this._descriptionElement.hidden = true;
|
|
1858
|
+
this._descriptionElement.id = 'color_picker_desc_' + nextDescriptionId++;
|
|
1859
|
+
wrapper.appendChild(this._descriptionElement);
|
|
1860
|
+
this._input.setAttribute('aria-describedby', this._descriptionElement.id);
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
_unwrapInput() {
|
|
1865
|
+
const wrapper = this._input.parentNode;
|
|
1866
|
+
if (wrapper && wrapper.classList.contains('color_picker-field')) {
|
|
1867
|
+
const parent = wrapper.parentNode;
|
|
1868
|
+
parent.insertBefore(this._input, wrapper);
|
|
1869
|
+
parent.removeChild(wrapper);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
_renderSwatches() {
|
|
1873
|
+
const swatches = this._swatches.map(normalizeSwatch).filter(swatch => this._alpha || !isTranslucentSwatch(swatch.value));
|
|
1874
|
+
this._swatchesContainer.textContent = '';
|
|
1875
|
+
this._swatchesContainer.classList.toggle('color_picker-empty', !swatches.length);
|
|
1876
|
+
if (!swatches.length) {
|
|
1877
|
+
return;
|
|
1878
|
+
}
|
|
1879
|
+
groupSwatches(swatches).forEach((group, index) => {
|
|
1880
|
+
if (index > 0) {
|
|
1881
|
+
const divider = document.createElement('span');
|
|
1882
|
+
divider.className = 'color_picker-swatch_divider';
|
|
1883
|
+
this._swatchesContainer.appendChild(divider);
|
|
1884
|
+
}
|
|
1885
|
+
group.swatches.forEach(({
|
|
1886
|
+
value,
|
|
1887
|
+
text
|
|
1888
|
+
}) => {
|
|
1889
|
+
const button = document.createElement('button');
|
|
1890
|
+
button.setAttribute('type', 'button');
|
|
1891
|
+
button.title = text;
|
|
1892
|
+
button.style.color = value;
|
|
1893
|
+
button.textContent = value;
|
|
1894
|
+
this._swatchesContainer.appendChild(button);
|
|
1895
|
+
});
|
|
1870
1896
|
});
|
|
1871
|
-
|
|
1897
|
+
}
|
|
1872
1898
|
|
|
1873
|
-
|
|
1874
|
-
|
|
1899
|
+
// Lifecycle
|
|
1900
|
+
|
|
1901
|
+
_open() {
|
|
1902
|
+
if (this._picker.classList.contains('color_picker-open')) {
|
|
1903
|
+
return;
|
|
1904
|
+
}
|
|
1905
|
+
this._picker.classList.add('color_picker-open');
|
|
1906
|
+
this._updatePosition();
|
|
1907
|
+
this._setColorFromStr(this._input.value);
|
|
1908
|
+
this._addDocListeners();
|
|
1909
|
+
}
|
|
1910
|
+
_close() {
|
|
1911
|
+
if (!this._picker.classList.contains('color_picker-open')) {
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
this._picker.classList.remove('color_picker-open');
|
|
1915
|
+
this._removeDocListeners();
|
|
1916
|
+
}
|
|
1917
|
+
_updatePosition() {
|
|
1918
|
+
const margin = 2;
|
|
1919
|
+
const pickerHeight = this._picker.offsetHeight;
|
|
1920
|
+
const pickerWidth = this._picker.offsetWidth;
|
|
1921
|
+
const inputRect = this._input.getBoundingClientRect();
|
|
1922
|
+
const clipRect = getClipRect(this._input);
|
|
1923
|
+
const spaceBelow = clipRect.bottom - inputRect.bottom;
|
|
1924
|
+
const flipTop = pickerHeight + margin > spaceBelow && pickerHeight + margin <= inputRect.top - clipRect.top;
|
|
1925
|
+
this._picker.classList.toggle('color_picker-top', flipTop);
|
|
1926
|
+
if (flipTop) {
|
|
1927
|
+
this._picker.style.top = 'auto';
|
|
1928
|
+
this._picker.style.bottom = `calc(100% + ${margin}px)`;
|
|
1929
|
+
} else {
|
|
1930
|
+
this._picker.style.top = `calc(100% + ${margin}px)`;
|
|
1931
|
+
this._picker.style.bottom = '';
|
|
1932
|
+
}
|
|
1933
|
+
if (inputRect.left + pickerWidth > clipRect.right) {
|
|
1934
|
+
this._picker.style.left = 'auto';
|
|
1935
|
+
this._picker.style.right = '0';
|
|
1936
|
+
} else {
|
|
1937
|
+
this._picker.style.left = '0';
|
|
1938
|
+
this._picker.style.right = '';
|
|
1939
|
+
}
|
|
1940
|
+
const areaRect = this._colorArea.getBoundingClientRect();
|
|
1941
|
+
this._colorAreaDims = {
|
|
1942
|
+
width: this._colorArea.offsetWidth,
|
|
1943
|
+
height: this._colorArea.offsetHeight,
|
|
1944
|
+
x: areaRect.x + window.scrollX,
|
|
1945
|
+
y: areaRect.y + window.scrollY
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
// Color interaction
|
|
1950
|
+
|
|
1951
|
+
_setColorFromStr(str, options) {
|
|
1952
|
+
this._updateColor(strToRGBA(str), options);
|
|
1953
|
+
const {
|
|
1954
|
+
h,
|
|
1955
|
+
s,
|
|
1956
|
+
v,
|
|
1957
|
+
a
|
|
1958
|
+
} = rgbaToHSVA(this._displayColor);
|
|
1959
|
+
this._hueSlider.value = h;
|
|
1960
|
+
this._picker.style.color = `hsl(${h}, 100%, 50%)`;
|
|
1961
|
+
this._hueMarker.style.left = `${h / 360 * 100}%`;
|
|
1962
|
+
this._colorMarker.style.left = `${this._colorAreaDims.width * s / 100}px`;
|
|
1963
|
+
this._colorMarker.style.top = `${this._colorAreaDims.height - this._colorAreaDims.height * v / 100}px`;
|
|
1964
|
+
this._alphaSlider.value = a * 100;
|
|
1965
|
+
this._alphaMarker.style.left = `${a * 100}%`;
|
|
1966
|
+
}
|
|
1967
|
+
_moveMarker(event) {
|
|
1968
|
+
let x = event.pageX - this._colorAreaDims.x;
|
|
1969
|
+
let y = event.pageY - this._colorAreaDims.y;
|
|
1970
|
+
this._setMarkerPosition(x, y);
|
|
1971
|
+
event.preventDefault();
|
|
1972
|
+
event.stopPropagation();
|
|
1973
|
+
}
|
|
1974
|
+
_moveMarkerOnKeydown(dx, dy) {
|
|
1975
|
+
let x = this._colorMarker.style.left.replace('px', '') * 1 + dx;
|
|
1976
|
+
let y = this._colorMarker.style.top.replace('px', '') * 1 + dy;
|
|
1977
|
+
this._setMarkerPosition(x, y);
|
|
1978
|
+
}
|
|
1979
|
+
_setHue() {
|
|
1980
|
+
const hue = this._hueSlider.value * 1;
|
|
1981
|
+
const x = this._colorMarker.style.left.replace('px', '') * 1;
|
|
1982
|
+
const y = this._colorMarker.style.top.replace('px', '') * 1;
|
|
1983
|
+
this._picker.style.color = `hsl(${hue}, 100%, 50%)`;
|
|
1984
|
+
this._hueMarker.style.left = `${hue / 360 * 100}%`;
|
|
1985
|
+
this._setColorAtPosition(x, y);
|
|
1986
|
+
}
|
|
1987
|
+
_setAlpha() {
|
|
1988
|
+
const alpha = this._alphaSlider.value / 100;
|
|
1989
|
+
this._alphaMarker.style.left = `${alpha * 100}%`;
|
|
1990
|
+
this._updateColor({
|
|
1991
|
+
a: alpha
|
|
1992
|
+
});
|
|
1993
|
+
this._syncInput();
|
|
1994
|
+
}
|
|
1995
|
+
_setMarkerPosition(x, y) {
|
|
1996
|
+
x = x < 0 ? 0 : x > this._colorAreaDims.width ? this._colorAreaDims.width : x;
|
|
1997
|
+
y = y < 0 ? 0 : y > this._colorAreaDims.height ? this._colorAreaDims.height : y;
|
|
1998
|
+
this._colorMarker.style.left = `${x}px`;
|
|
1999
|
+
this._colorMarker.style.top = `${y}px`;
|
|
2000
|
+
this._setColorAtPosition(x, y);
|
|
2001
|
+
this._colorMarker.focus();
|
|
2002
|
+
}
|
|
2003
|
+
_setColorAtPosition(x, y) {
|
|
2004
|
+
const hsva = {
|
|
2005
|
+
h: this._hueSlider.value * 1,
|
|
2006
|
+
s: x / this._colorAreaDims.width * 100,
|
|
2007
|
+
v: 100 - y / this._colorAreaDims.height * 100,
|
|
2008
|
+
a: this._alphaSlider.value / 100
|
|
2009
|
+
};
|
|
2010
|
+
const rgba = hsvaToRGBA(hsva);
|
|
2011
|
+
this._updateColor(rgba);
|
|
2012
|
+
this._syncInput();
|
|
2013
|
+
}
|
|
2014
|
+
_updateColor(rgba, {
|
|
2015
|
+
silent
|
|
2016
|
+
} = {}) {
|
|
2017
|
+
rgba = rgba || this._defaultColor;
|
|
2018
|
+
if (rgba && !this._alpha) rgba.a = 1;
|
|
2019
|
+
this._currentColor = rgba && {
|
|
2020
|
+
...this._displayColor,
|
|
2021
|
+
...rgba
|
|
2022
|
+
};
|
|
2023
|
+
this._displayColor = this._currentColor || this._fallbackColor || DEFAULT_DISPLAY_COLOR;
|
|
2024
|
+
const hex = rgbaToHex(this._displayColor);
|
|
2025
|
+
const opaqueHex = hex.substring(0, 7);
|
|
2026
|
+
this._colorMarker.style.color = opaqueHex;
|
|
2027
|
+
this._alphaMarker.parentNode.style.color = opaqueHex;
|
|
2028
|
+
this._alphaMarker.style.color = hex;
|
|
2029
|
+
const formatted = this._formatHex(this._currentColor);
|
|
2030
|
+
const fallbackHex = this._formatHex(this._fallbackColor);
|
|
2031
|
+
const wrapper = this._input.parentNode;
|
|
2032
|
+
if (wrapper && wrapper.classList.contains('color_picker-field')) {
|
|
2033
|
+
wrapper.style.color = formatted || fallbackHex || '';
|
|
2034
|
+
}
|
|
2035
|
+
if (this._descriptionElement) {
|
|
2036
|
+
this._descriptionElement.textContent = !formatted && fallbackHex ? `${this._fallbackColorDescription}: ${fallbackHex}` : '';
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
// Force repaint the color and alpha gradients (Chrome workaround)
|
|
2040
|
+
this._colorArea.style.display = 'none';
|
|
2041
|
+
this._colorArea.offsetHeight;
|
|
2042
|
+
this._colorArea.style.display = '';
|
|
2043
|
+
this._alphaMarker.nextElementSibling.style.display = 'none';
|
|
2044
|
+
this._alphaMarker.nextElementSibling.offsetHeight;
|
|
2045
|
+
this._alphaMarker.nextElementSibling.style.display = '';
|
|
2046
|
+
if (!silent && this._onChange) this._onChange(formatted);
|
|
2047
|
+
}
|
|
2048
|
+
_syncInput() {
|
|
2049
|
+
this._input.value = this._formatHex(this._currentColor) || '';
|
|
2050
|
+
}
|
|
2051
|
+
_formatHex(rgba) {
|
|
2052
|
+
if (!rgba) return null;
|
|
2053
|
+
const hex = rgbaToHex(rgba);
|
|
2054
|
+
return rgba.a < 1 ? hex : hex.substring(0, 7);
|
|
2055
|
+
}
|
|
2056
|
+
_normalizeInputValue() {
|
|
2057
|
+
const hex = this._formatHex(this._currentColor) || '';
|
|
2058
|
+
if (hex !== this._input.value) {
|
|
2059
|
+
this._input.value = hex;
|
|
1875
2060
|
}
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// Event wiring
|
|
1876
2064
|
|
|
1877
|
-
|
|
2065
|
+
_bindEvents() {
|
|
2066
|
+
this._onInputClick = () => {
|
|
2067
|
+
this._open();
|
|
2068
|
+
};
|
|
2069
|
+
this._onInputKeydown = event => {
|
|
2070
|
+
if (event.key === 'Enter') {
|
|
2071
|
+
this._normalizeInputValue();
|
|
2072
|
+
}
|
|
2073
|
+
if (this._picker.classList.contains('color_picker-open')) {
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
if (event.key === 'Enter' || event.key === 'ArrowDown' && event.altKey) {
|
|
2077
|
+
this._open();
|
|
2078
|
+
event.stopPropagation();
|
|
2079
|
+
}
|
|
2080
|
+
};
|
|
2081
|
+
this._onPickerMousedown = event => {
|
|
2082
|
+
this._picker.classList.remove('color_picker-keyboard_nav');
|
|
2083
|
+
event.stopPropagation();
|
|
2084
|
+
};
|
|
2085
|
+
this._onAreaPointerdown = event => {
|
|
2086
|
+
event.preventDefault();
|
|
2087
|
+
this._colorArea.setPointerCapture(event.pointerId);
|
|
2088
|
+
this._dragging = true;
|
|
2089
|
+
};
|
|
2090
|
+
this._onAreaPointermove = event => {
|
|
2091
|
+
if (this._dragging) {
|
|
2092
|
+
this._moveMarker(event);
|
|
2093
|
+
}
|
|
2094
|
+
};
|
|
2095
|
+
this._onAreaPointerup = () => {
|
|
2096
|
+
this._dragging = false;
|
|
2097
|
+
};
|
|
2098
|
+
this._onInputEvent = () => {
|
|
2099
|
+
if (this._picker.classList.contains('color_picker-open')) {
|
|
2100
|
+
this._setColorFromStr(this._input.value);
|
|
2101
|
+
} else {
|
|
2102
|
+
this._updateColor(strToRGBA(this._input.value));
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
this._onSwatchClick = event => {
|
|
2106
|
+
if (event.target.closest('.color_picker-swatches button')) {
|
|
2107
|
+
this._setColorFromStr(event.target.closest('.color_picker-swatches button').textContent);
|
|
2108
|
+
this._syncInput();
|
|
2109
|
+
}
|
|
2110
|
+
};
|
|
2111
|
+
this._onMarkerKeydown = event => {
|
|
2112
|
+
const movements = {
|
|
2113
|
+
ArrowUp: [0, -1],
|
|
2114
|
+
ArrowDown: [0, 1],
|
|
2115
|
+
ArrowLeft: [-1, 0],
|
|
2116
|
+
ArrowRight: [1, 0]
|
|
2117
|
+
};
|
|
2118
|
+
if (movements[event.key]) {
|
|
2119
|
+
this._moveMarkerOnKeydown(...movements[event.key]);
|
|
2120
|
+
event.preventDefault();
|
|
2121
|
+
}
|
|
2122
|
+
};
|
|
2123
|
+
this._onAreaClick = event => this._moveMarker(event);
|
|
2124
|
+
this._onHueInput = () => this._setHue();
|
|
2125
|
+
this._onAlphaInput = () => this._setAlpha();
|
|
2126
|
+
const wrapper = this._input.parentNode;
|
|
2127
|
+
this._onFocusout = event => {
|
|
2128
|
+
if (event.target === this._input) {
|
|
2129
|
+
this._normalizeInputValue();
|
|
2130
|
+
}
|
|
2131
|
+
if (this._picker.classList.contains('color_picker-open')) {
|
|
2132
|
+
if (event.relatedTarget && !wrapper.contains(event.relatedTarget)) {
|
|
2133
|
+
this._close();
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
};
|
|
2137
|
+
this._input.addEventListener('click', this._onInputClick);
|
|
2138
|
+
this._input.addEventListener('keydown', this._onInputKeydown);
|
|
2139
|
+
this._input.addEventListener('input', this._onInputEvent);
|
|
2140
|
+
wrapper.addEventListener('focusout', this._onFocusout);
|
|
2141
|
+
this._picker.addEventListener('mousedown', this._onPickerMousedown);
|
|
2142
|
+
this._colorArea.addEventListener('pointerdown', this._onAreaPointerdown);
|
|
2143
|
+
this._colorArea.addEventListener('pointermove', this._onAreaPointermove);
|
|
2144
|
+
this._colorArea.addEventListener('pointerup', this._onAreaPointerup);
|
|
2145
|
+
this._swatchesContainer.addEventListener('click', this._onSwatchClick);
|
|
2146
|
+
this._colorMarker.addEventListener('keydown', this._onMarkerKeydown);
|
|
2147
|
+
this._colorArea.addEventListener('click', this._onAreaClick);
|
|
2148
|
+
this._hueSlider.addEventListener('input', this._onHueInput);
|
|
2149
|
+
this._alphaSlider.addEventListener('input', this._onAlphaInput);
|
|
2150
|
+
}
|
|
2151
|
+
_unbindEvents() {
|
|
2152
|
+
this._input.removeEventListener('click', this._onInputClick);
|
|
2153
|
+
this._input.removeEventListener('keydown', this._onInputKeydown);
|
|
2154
|
+
this._input.removeEventListener('input', this._onInputEvent);
|
|
2155
|
+
const wrapper = this._input.parentNode;
|
|
2156
|
+
if (wrapper && wrapper.classList.contains('color_picker-field')) {
|
|
2157
|
+
wrapper.removeEventListener('focusout', this._onFocusout);
|
|
2158
|
+
}
|
|
2159
|
+
this._picker.removeEventListener('mousedown', this._onPickerMousedown);
|
|
2160
|
+
this._colorArea.removeEventListener('pointerdown', this._onAreaPointerdown);
|
|
2161
|
+
this._colorArea.removeEventListener('pointermove', this._onAreaPointermove);
|
|
2162
|
+
this._colorArea.removeEventListener('pointerup', this._onAreaPointerup);
|
|
2163
|
+
this._swatchesContainer.removeEventListener('click', this._onSwatchClick);
|
|
2164
|
+
this._colorMarker.removeEventListener('keydown', this._onMarkerKeydown);
|
|
2165
|
+
this._colorArea.removeEventListener('click', this._onAreaClick);
|
|
2166
|
+
this._hueSlider.removeEventListener('input', this._onHueInput);
|
|
2167
|
+
this._alphaSlider.removeEventListener('input', this._onAlphaInput);
|
|
2168
|
+
this._removeDocListeners();
|
|
2169
|
+
}
|
|
2170
|
+
_addDocListeners() {
|
|
2171
|
+
this._onDocMousedown = event => {
|
|
2172
|
+
this._picker.classList.remove('color_picker-keyboard_nav');
|
|
2173
|
+
if (!this._input.parentNode.contains(event.target)) {
|
|
2174
|
+
this._close();
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
this._onDocKeydown = event => {
|
|
2178
|
+
if (event.key === 'Escape' || event.key === 'Enter' && event.target.tagName !== 'BUTTON') {
|
|
2179
|
+
this._close();
|
|
2180
|
+
this._input.focus({
|
|
2181
|
+
preventScroll: true
|
|
2182
|
+
});
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
const navKeys = ['Tab', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];
|
|
2186
|
+
if (navKeys.includes(event.key)) {
|
|
2187
|
+
this._picker.classList.add('color_picker-keyboard_nav');
|
|
2188
|
+
}
|
|
2189
|
+
};
|
|
2190
|
+
document.addEventListener('mousedown', this._onDocMousedown);
|
|
2191
|
+
document.addEventListener('keydown', this._onDocKeydown);
|
|
2192
|
+
}
|
|
2193
|
+
_removeDocListeners() {
|
|
2194
|
+
if (this._onDocMousedown) {
|
|
2195
|
+
document.removeEventListener('mousedown', this._onDocMousedown);
|
|
2196
|
+
document.removeEventListener('keydown', this._onDocKeydown);
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
function strToRGBA(str) {
|
|
2201
|
+
if (!str) return null;
|
|
2202
|
+
const regex = /^((rgba)|rgb)[\D]+([\d.]+)[\D]+([\d.]+)[\D]+([\d.]+)[\D]*?([\d.]+|$)/i;
|
|
2203
|
+
let match, rgba;
|
|
2204
|
+
if (!ctx) {
|
|
2205
|
+
match = regex.exec(str);
|
|
2206
|
+
if (match) {
|
|
2207
|
+
return {
|
|
2208
|
+
r: match[3] * 1,
|
|
2209
|
+
g: match[4] * 1,
|
|
2210
|
+
b: match[5] * 1,
|
|
2211
|
+
a: match[6] * 1 || 1
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2214
|
+
if (!/^#[0-9a-f]{3,8}$/i.test(str)) return null;
|
|
2215
|
+
let hex = str.replace('#', '');
|
|
2216
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
2217
|
+
hex = hex.split('').map(c => c + c).join('');
|
|
2218
|
+
}
|
|
2219
|
+
if (hex.length !== 6 && hex.length !== 8) return null;
|
|
2220
|
+
match = hex.match(/.{2}/g).map(h => parseInt(h, 16));
|
|
2221
|
+
return {
|
|
2222
|
+
r: match[0],
|
|
2223
|
+
g: match[1],
|
|
2224
|
+
b: match[2],
|
|
2225
|
+
a: match[3] !== undefined ? match[3] / 255 : 1
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
ctx.fillStyle = '#010101';
|
|
2229
|
+
ctx.fillStyle = str;
|
|
2230
|
+
if (ctx.fillStyle === '#010101') {
|
|
2231
|
+
ctx.fillStyle = '#020202';
|
|
2232
|
+
ctx.fillStyle = str;
|
|
2233
|
+
if (ctx.fillStyle === '#020202') return null;
|
|
2234
|
+
}
|
|
2235
|
+
match = regex.exec(ctx.fillStyle);
|
|
2236
|
+
if (match) {
|
|
2237
|
+
rgba = {
|
|
2238
|
+
r: match[3] * 1,
|
|
2239
|
+
g: match[4] * 1,
|
|
2240
|
+
b: match[5] * 1,
|
|
2241
|
+
a: match[6] * 1
|
|
2242
|
+
};
|
|
2243
|
+
} else {
|
|
2244
|
+
match = ctx.fillStyle.replace('#', '').match(/.{2}/g).map(h => parseInt(h, 16));
|
|
2245
|
+
rgba = {
|
|
2246
|
+
r: match[0],
|
|
2247
|
+
g: match[1],
|
|
2248
|
+
b: match[2],
|
|
2249
|
+
a: 1
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
return rgba;
|
|
2253
|
+
}
|
|
2254
|
+
function rgbaToHSVA(rgba) {
|
|
2255
|
+
const red = rgba.r / 255;
|
|
2256
|
+
const green = rgba.g / 255;
|
|
2257
|
+
const blue = rgba.b / 255;
|
|
2258
|
+
const xmax = Math.max(red, green, blue);
|
|
2259
|
+
const xmin = Math.min(red, green, blue);
|
|
2260
|
+
const chroma = xmax - xmin;
|
|
2261
|
+
const value = xmax;
|
|
2262
|
+
let hue = 0;
|
|
2263
|
+
let saturation = 0;
|
|
2264
|
+
if (chroma) {
|
|
2265
|
+
if (xmax === red) {
|
|
2266
|
+
hue = (green - blue) / chroma;
|
|
2267
|
+
}
|
|
2268
|
+
if (xmax === green) {
|
|
2269
|
+
hue = 2 + (blue - red) / chroma;
|
|
2270
|
+
}
|
|
2271
|
+
if (xmax === blue) {
|
|
2272
|
+
hue = 4 + (red - green) / chroma;
|
|
2273
|
+
}
|
|
2274
|
+
if (xmax) {
|
|
2275
|
+
saturation = chroma / xmax;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
hue = Math.floor(hue * 60);
|
|
2279
|
+
return {
|
|
2280
|
+
h: hue < 0 ? hue + 360 : hue,
|
|
2281
|
+
s: Math.round(saturation * 100),
|
|
2282
|
+
v: Math.round(value * 100),
|
|
2283
|
+
a: rgba.a
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
function hsvaToRGBA(hsva) {
|
|
2287
|
+
const saturation = hsva.s / 100;
|
|
2288
|
+
const value = hsva.v / 100;
|
|
2289
|
+
let chroma = saturation * value;
|
|
2290
|
+
let hueBy60 = hsva.h / 60;
|
|
2291
|
+
let x = chroma * (1 - Math.abs(hueBy60 % 2 - 1));
|
|
2292
|
+
let m = value - chroma;
|
|
2293
|
+
chroma = chroma + m;
|
|
2294
|
+
x = x + m;
|
|
2295
|
+
const index = Math.floor(hueBy60) % 6;
|
|
2296
|
+
const red = [chroma, x, m, m, x, chroma][index];
|
|
2297
|
+
const green = [x, chroma, chroma, x, m, m][index];
|
|
2298
|
+
const blue = [m, m, x, chroma, chroma, x][index];
|
|
2299
|
+
return {
|
|
2300
|
+
r: Math.round(red * 255),
|
|
2301
|
+
g: Math.round(green * 255),
|
|
2302
|
+
b: Math.round(blue * 255),
|
|
2303
|
+
a: hsva.a
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
function rgbaToHex(rgba) {
|
|
2307
|
+
let R = rgba.r.toString(16);
|
|
2308
|
+
let G = rgba.g.toString(16);
|
|
2309
|
+
let B = rgba.b.toString(16);
|
|
2310
|
+
let A = Math.round(rgba.a * 255).toString(16);
|
|
2311
|
+
if (rgba.r < 16) {
|
|
2312
|
+
R = '0' + R;
|
|
2313
|
+
}
|
|
2314
|
+
if (rgba.g < 16) {
|
|
2315
|
+
G = '0' + G;
|
|
2316
|
+
}
|
|
2317
|
+
if (rgba.b < 16) {
|
|
2318
|
+
B = '0' + B;
|
|
2319
|
+
}
|
|
2320
|
+
if (rgba.a * 255 < 16) {
|
|
2321
|
+
A = '0' + A;
|
|
2322
|
+
}
|
|
2323
|
+
return '#' + R + G + B + A;
|
|
2324
|
+
}
|
|
2325
|
+
function getClipRect(element) {
|
|
2326
|
+
const viewport = {
|
|
2327
|
+
top: 0,
|
|
2328
|
+
left: 0,
|
|
2329
|
+
right: document.documentElement.clientWidth,
|
|
2330
|
+
bottom: document.documentElement.clientHeight
|
|
2331
|
+
};
|
|
2332
|
+
let ancestor = element.parentElement;
|
|
2333
|
+
while (ancestor && ancestor !== document.documentElement) {
|
|
2334
|
+
const overflow = getComputedStyle(ancestor).overflow;
|
|
2335
|
+
if (overflow !== 'visible') {
|
|
2336
|
+
const rect = ancestor.getBoundingClientRect();
|
|
2337
|
+
return {
|
|
2338
|
+
top: Math.max(viewport.top, rect.top),
|
|
2339
|
+
left: Math.max(viewport.left, rect.left),
|
|
2340
|
+
right: Math.min(viewport.right, rect.right),
|
|
2341
|
+
bottom: Math.min(viewport.bottom, rect.bottom)
|
|
2342
|
+
};
|
|
2343
|
+
}
|
|
2344
|
+
ancestor = ancestor.parentElement;
|
|
2345
|
+
}
|
|
2346
|
+
return viewport;
|
|
2347
|
+
}
|
|
2348
|
+
function isTranslucentSwatch(str) {
|
|
2349
|
+
return str.length > 7 && str.slice(-2).toLowerCase() !== 'ff';
|
|
2350
|
+
}
|
|
2351
|
+
function normalizeSwatch(swatch) {
|
|
2352
|
+
return typeof swatch === 'string' ? {
|
|
2353
|
+
value: swatch,
|
|
2354
|
+
text: swatch
|
|
2355
|
+
} : {
|
|
2356
|
+
value: swatch.value,
|
|
2357
|
+
text: swatch.text || swatch.value,
|
|
2358
|
+
group: swatch.group
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
function groupSwatches(swatches) {
|
|
2362
|
+
const groups = [];
|
|
2363
|
+
const groupsByKey = new Map();
|
|
2364
|
+
swatches.forEach(swatch => {
|
|
2365
|
+
const key = swatch.group || '';
|
|
2366
|
+
let group = groupsByKey.get(key);
|
|
2367
|
+
if (!group) {
|
|
2368
|
+
group = {
|
|
2369
|
+
key,
|
|
2370
|
+
swatches: []
|
|
2371
|
+
};
|
|
2372
|
+
groupsByKey.set(key, group);
|
|
2373
|
+
groups.push(group);
|
|
2374
|
+
}
|
|
2375
|
+
group.swatches.push(swatch);
|
|
2376
|
+
});
|
|
2377
|
+
return groups;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
function template$8(data) {
|
|
2381
|
+
var __p = '';
|
|
2382
|
+
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" dir="auto" autocomplete="off" />\n';
|
|
2383
|
+
return __p
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* Input view for a color value in hex representation.
|
|
2388
|
+
*
|
|
2389
|
+
* See {@link inputWithPlaceholderText} for placeholder related
|
|
2390
|
+
* further options. See {@link inputView} for further options.
|
|
2391
|
+
*
|
|
2392
|
+
* @param {Object} [options]
|
|
2393
|
+
*
|
|
2394
|
+
* @param {string|function} [options.defaultValue]
|
|
2395
|
+
* Color value to display by default. The corresponding value is not
|
|
2396
|
+
* stored in the model. Selecting the default value when a different
|
|
2397
|
+
* value was set before, unsets the attribute in the model.
|
|
2398
|
+
*
|
|
2399
|
+
* @param {string} [options.defaultValueBinding]
|
|
2400
|
+
* Name of an attribute the default value depends on. If a function
|
|
2401
|
+
* is used as defaultValue option, it will be passed the value of the
|
|
2402
|
+
* defaultValueBinding attribute each time it changes. If no
|
|
2403
|
+
* defaultValue option is set, the value of the defaultValueBinding
|
|
2404
|
+
* attribute will be used as default value.
|
|
2405
|
+
*
|
|
2406
|
+
* @param {string|function} [options.placeholderColor]
|
|
2407
|
+
* Color to display in swatch by default.
|
|
2408
|
+
*
|
|
2409
|
+
* @param {string} [options.placeholderColorBinding]
|
|
2410
|
+
* Name of an attribute the placeholder color depends on. If a function
|
|
2411
|
+
* is used as placeholderColor option, it will be passed the value of the
|
|
2412
|
+
* placeholderColorBinding attribute each time it changes.
|
|
2413
|
+
*
|
|
2414
|
+
* @param {boolean} [options.alpha]
|
|
2415
|
+
* Allow picking colors with alpha channel. When enabled, translucent
|
|
2416
|
+
* colors are stored in `#rrggbbaa` format. Fully opaque colors still
|
|
2417
|
+
* use `#rrggbb`.
|
|
2418
|
+
*
|
|
2419
|
+
* @param {Array<string|{value: string, text: string, group: string}>} [options.swatches]
|
|
2420
|
+
* Preset colors to be displayed inside the picker drop down. Each
|
|
2421
|
+
* entry is either a color string or an object with a `value` color,
|
|
2422
|
+
* a `text` label shown as the swatch's tooltip and an optional
|
|
2423
|
+
* `group` key. Consecutive swatches with a different `group` are
|
|
2424
|
+
* separated by a divider in the picker. The default value, if
|
|
2425
|
+
* present, is always used as the first swatch automatically. Swatches
|
|
2426
|
+
* are deduplicated by value.
|
|
2427
|
+
*
|
|
2428
|
+
* @class
|
|
2429
|
+
*/
|
|
2430
|
+
const ColorInputView = Marionette.ItemView.extend({
|
|
2431
|
+
mixins: [inputView, inputWithPlaceholderText],
|
|
2432
|
+
template: template$8,
|
|
2433
|
+
className: 'color_input',
|
|
2434
|
+
ui: {
|
|
2435
|
+
input: 'input'
|
|
1878
2436
|
},
|
|
1879
|
-
|
|
1880
|
-
this.
|
|
1881
|
-
this.ui.input
|
|
2437
|
+
onRender: function () {
|
|
2438
|
+
this.setupAttributeBinding('placeholderColor', this.updatePlaceholderColor);
|
|
2439
|
+
this._colorPicker = new ColorPicker(this.ui.input[0], {
|
|
2440
|
+
alpha: this.options.alpha,
|
|
1882
2441
|
defaultValue: this.defaultValue(),
|
|
1883
|
-
|
|
2442
|
+
fallbackColor: this.getAttributeBoundOption('placeholderColor'),
|
|
2443
|
+
fallbackColorDescription: this.options.placeholderColorDescription,
|
|
2444
|
+
swatches: this.getSwatches(),
|
|
2445
|
+
onChange: this._debouncedOnChange()
|
|
1884
2446
|
});
|
|
2447
|
+
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2448
|
+
if (this.options.defaultValueBinding) {
|
|
2449
|
+
this.listenTo(this.model, 'change:' + this.options.defaultValueBinding, this.updateSettings);
|
|
2450
|
+
}
|
|
1885
2451
|
this.load();
|
|
1886
2452
|
},
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
delete settings.swatches;
|
|
1893
|
-
this.ui.input.data('minicolors-settings', settings);
|
|
2453
|
+
updatePlaceholderColor(value) {
|
|
2454
|
+
if (this._colorPicker) {
|
|
2455
|
+
this._colorPicker.update({
|
|
2456
|
+
fallbackColor: value
|
|
2457
|
+
});
|
|
1894
2458
|
}
|
|
1895
2459
|
},
|
|
1896
|
-
|
|
2460
|
+
updateSettings: function () {
|
|
2461
|
+
this._colorPicker.update({
|
|
2462
|
+
defaultValue: this.defaultValue(),
|
|
2463
|
+
swatches: this.getSwatches()
|
|
2464
|
+
});
|
|
2465
|
+
this.load();
|
|
2466
|
+
},
|
|
2467
|
+
load: function () {
|
|
2468
|
+
var color = this.model.get(this.options.propertyName) || this.defaultValue() || '';
|
|
1897
2469
|
if (!this._saving) {
|
|
1898
|
-
this.
|
|
2470
|
+
this._colorPicker.setValue(color);
|
|
1899
2471
|
}
|
|
1900
|
-
|
|
1901
2472
|
this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
|
|
1902
2473
|
},
|
|
1903
|
-
|
|
1904
|
-
this.
|
|
2474
|
+
onBeforeClose: function () {
|
|
2475
|
+
this._colorPicker.destroy();
|
|
1905
2476
|
},
|
|
1906
|
-
getSwatches: function
|
|
1907
|
-
return _.chain([this.defaultValue(), this.options.swatches]).flatten().
|
|
2477
|
+
getSwatches: function () {
|
|
2478
|
+
return _.chain([this.defaultValue(), this.options.swatches]).flatten().compact().map(swatch => typeof swatch === 'string' ? {
|
|
2479
|
+
value: swatch
|
|
2480
|
+
} : swatch).uniq(swatch => swatch.value).value();
|
|
1908
2481
|
},
|
|
1909
|
-
defaultValue: function
|
|
2482
|
+
defaultValue: function () {
|
|
1910
2483
|
var bindingValue;
|
|
1911
|
-
|
|
1912
2484
|
if (this.options.defaultValueBinding) {
|
|
1913
2485
|
bindingValue = this.model.get(this.options.defaultValueBinding);
|
|
1914
2486
|
}
|
|
1915
|
-
|
|
1916
2487
|
if (typeof this.options.defaultValue === 'function') {
|
|
1917
2488
|
return this.options.defaultValue(bindingValue);
|
|
1918
2489
|
} else if ('defaultValue' in this.options) {
|
|
@@ -1920,10 +2491,23 @@ var ColorInputView = Marionette.ItemView.extend({
|
|
|
1920
2491
|
} else {
|
|
1921
2492
|
return bindingValue;
|
|
1922
2493
|
}
|
|
2494
|
+
},
|
|
2495
|
+
_debouncedOnChange: function () {
|
|
2496
|
+
const handler = _.bind(this._onChange, this);
|
|
2497
|
+
return this.options.disableChangeDebounce ? handler : _.debounce(handler, 200);
|
|
2498
|
+
},
|
|
2499
|
+
_onChange: function (color) {
|
|
2500
|
+
this._saving = true;
|
|
2501
|
+
if (!color || color === this.defaultValue()) {
|
|
2502
|
+
this.model.unset(this.options.propertyName);
|
|
2503
|
+
} else {
|
|
2504
|
+
this.model.set(this.options.propertyName, color);
|
|
2505
|
+
}
|
|
2506
|
+
this._saving = false;
|
|
1923
2507
|
}
|
|
1924
2508
|
});
|
|
1925
2509
|
|
|
1926
|
-
function template$
|
|
2510
|
+
function template$9(data) {
|
|
1927
2511
|
var __p = '';
|
|
1928
2512
|
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<select></select>';
|
|
1929
2513
|
return __p
|
|
@@ -1935,8 +2519,12 @@ return __p
|
|
|
1935
2519
|
*
|
|
1936
2520
|
* @param {Object} [options]
|
|
1937
2521
|
*
|
|
1938
|
-
* @param {string[]} [options.values]
|
|
1939
|
-
* List of possible values to persist in the attribute.
|
|
2522
|
+
* @param {string[]|function} [options.values]
|
|
2523
|
+
* List of possible values to persist in the attribute. Pass a
|
|
2524
|
+
* function returning the list to defer reading the values.
|
|
2525
|
+
*
|
|
2526
|
+
* @param {number} [options.defaultValue]
|
|
2527
|
+
* Default value to display if property is not set.
|
|
1940
2528
|
*
|
|
1941
2529
|
* @param {string[]} [options.texts]
|
|
1942
2530
|
* List of display texts for drop down items.
|
|
@@ -1985,7 +2573,10 @@ return __p
|
|
|
1985
2573
|
* Display text for the blank item.
|
|
1986
2574
|
*
|
|
1987
2575
|
* @param {string} [options.blankTranslationKey]
|
|
1988
|
-
* Translation key to obtain display text for blank item.
|
|
2576
|
+
* Translation key to obtain display text for blank item. If neither
|
|
2577
|
+
* `blankText` nor `blankTranslationKey` are provided, the blank text
|
|
2578
|
+
* will be determined using `attributeTranslationKeyPrefixes` with
|
|
2579
|
+
* the suffix `blank`, similar to how labels are determined.
|
|
1989
2580
|
*
|
|
1990
2581
|
* @param {string} [options.placeholderValue]
|
|
1991
2582
|
* Include an item that sets the value of the attribute to a blank
|
|
@@ -2007,10 +2598,9 @@ return __p
|
|
|
2007
2598
|
*
|
|
2008
2599
|
* @class
|
|
2009
2600
|
*/
|
|
2010
|
-
|
|
2011
|
-
var SelectInputView = Marionette.ItemView.extend({
|
|
2601
|
+
const SelectInputView = Marionette.ItemView.extend({
|
|
2012
2602
|
mixins: [inputView],
|
|
2013
|
-
template: template$
|
|
2603
|
+
template: template$9,
|
|
2014
2604
|
events: {
|
|
2015
2605
|
'change': 'save'
|
|
2016
2606
|
},
|
|
@@ -2018,23 +2608,21 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2018
2608
|
select: 'select',
|
|
2019
2609
|
input: 'select'
|
|
2020
2610
|
},
|
|
2021
|
-
initialize: function
|
|
2611
|
+
initialize: function () {
|
|
2612
|
+
this.options.values = _.result(this.options, 'values');
|
|
2022
2613
|
if (this.options.collection) {
|
|
2023
2614
|
this.options.values = _.pluck(this.options.collection, this.options.valueProperty);
|
|
2024
|
-
|
|
2025
2615
|
if (this.options.textProperty) {
|
|
2026
2616
|
this.options.texts = _.pluck(this.options.collection, this.options.textProperty);
|
|
2027
2617
|
} else if (this.options.translationKeyProperty) {
|
|
2028
2618
|
this.options.translationKeys = _.pluck(this.options.collection, this.options.translationKeyProperty);
|
|
2029
2619
|
}
|
|
2030
|
-
|
|
2031
2620
|
if (this.options.groupProperty) {
|
|
2032
2621
|
this.options.groups = _.pluck(this.options.collection, this.options.groupProperty);
|
|
2033
2622
|
} else if (this.options.groupTranslationKeyProperty) {
|
|
2034
2623
|
this.options.groupTanslationKeys = _.pluck(this.options.collection, this.options.groupTranslationKeyProperty);
|
|
2035
2624
|
}
|
|
2036
2625
|
}
|
|
2037
|
-
|
|
2038
2626
|
if (!this.options.texts) {
|
|
2039
2627
|
if (!this.options.translationKeys) {
|
|
2040
2628
|
var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
|
|
@@ -2044,53 +2632,50 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2044
2632
|
return translationKeyPrefix + '.' + value;
|
|
2045
2633
|
}, this);
|
|
2046
2634
|
}
|
|
2047
|
-
|
|
2048
2635
|
this.options.texts = _.map(this.options.translationKeys, function (key) {
|
|
2049
2636
|
return I18n$1.t(key);
|
|
2050
2637
|
});
|
|
2051
2638
|
}
|
|
2052
|
-
|
|
2053
2639
|
if (!this.options.groups) {
|
|
2054
2640
|
this.options.groups = _.map(this.options.groupTanslationKeys, function (key) {
|
|
2055
2641
|
return I18n$1.t(key);
|
|
2056
2642
|
});
|
|
2057
2643
|
}
|
|
2058
|
-
|
|
2059
2644
|
this.optGroups = {};
|
|
2060
2645
|
},
|
|
2061
|
-
onRender: function
|
|
2646
|
+
onRender: function () {
|
|
2062
2647
|
this.appendBlank();
|
|
2063
2648
|
this.appendPlaceholder();
|
|
2064
2649
|
this.appendOptions();
|
|
2065
2650
|
this.load();
|
|
2066
2651
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2067
|
-
|
|
2068
2652
|
if (this.options.ensureValueDefined && !this.model.has(this.options.propertyName)) {
|
|
2069
2653
|
this.save();
|
|
2070
2654
|
}
|
|
2071
2655
|
},
|
|
2072
|
-
appendBlank: function
|
|
2656
|
+
appendBlank: function () {
|
|
2073
2657
|
if (!this.options.includeBlank) {
|
|
2074
2658
|
return;
|
|
2075
2659
|
}
|
|
2076
|
-
|
|
2660
|
+
var blankText = this.options.blankText;
|
|
2077
2661
|
if (this.options.blankTranslationKey) {
|
|
2078
|
-
|
|
2662
|
+
blankText = I18n$1.t(this.options.blankTranslationKey);
|
|
2663
|
+
} else if (!blankText) {
|
|
2664
|
+
blankText = findTranslation(this.attributeTranslationKeys('blank'), {
|
|
2665
|
+
defaultValue: I18n$1.t('pageflow.ui.views.inputs.select_input_view.none')
|
|
2666
|
+
});
|
|
2079
2667
|
}
|
|
2080
|
-
|
|
2081
2668
|
var option = document.createElement('option');
|
|
2082
2669
|
option.value = '';
|
|
2083
|
-
option.text =
|
|
2670
|
+
option.text = blankText;
|
|
2084
2671
|
this.ui.select.append(option);
|
|
2085
2672
|
},
|
|
2086
|
-
appendPlaceholder: function
|
|
2673
|
+
appendPlaceholder: function () {
|
|
2087
2674
|
if (!this.options.placeholderModel && !this.options.placeholderValue) {
|
|
2088
2675
|
return;
|
|
2089
2676
|
}
|
|
2090
|
-
|
|
2091
2677
|
var placeholderValue = this.options.placeholderValue || this.options.placeholderModel.get(this.options.propertyName);
|
|
2092
2678
|
var placeholderIndex = this.options.values.indexOf(placeholderValue);
|
|
2093
|
-
|
|
2094
2679
|
if (placeholderIndex >= 0) {
|
|
2095
2680
|
var option = document.createElement('option');
|
|
2096
2681
|
option.value = '';
|
|
@@ -2100,17 +2685,15 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2100
2685
|
this.ui.select.append(option);
|
|
2101
2686
|
}
|
|
2102
2687
|
},
|
|
2103
|
-
appendOptions: function
|
|
2688
|
+
appendOptions: function () {
|
|
2104
2689
|
_.each(this.options.values, function (value, index) {
|
|
2105
2690
|
var option = document.createElement('option');
|
|
2106
2691
|
var group = this.options.groups[index];
|
|
2107
2692
|
option.value = value;
|
|
2108
2693
|
option.text = this.options.texts[index];
|
|
2109
|
-
|
|
2110
2694
|
if (this.options.optionDisabled && this.options.optionDisabled(value)) {
|
|
2111
2695
|
option.setAttribute('disabled', true);
|
|
2112
2696
|
}
|
|
2113
|
-
|
|
2114
2697
|
if (group) {
|
|
2115
2698
|
option.setAttribute('data-group', group);
|
|
2116
2699
|
this.findOrCreateOptGroup(group).append(option);
|
|
@@ -2119,24 +2702,29 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2119
2702
|
}
|
|
2120
2703
|
}, this);
|
|
2121
2704
|
},
|
|
2122
|
-
findOrCreateOptGroup: function
|
|
2705
|
+
findOrCreateOptGroup: function (label) {
|
|
2123
2706
|
if (!this.optGroups[label]) {
|
|
2124
2707
|
this.optGroups[label] = $('<optgroup />', {
|
|
2125
2708
|
label: label
|
|
2126
2709
|
}).appendTo(this.ui.select);
|
|
2127
2710
|
}
|
|
2128
|
-
|
|
2129
2711
|
return this.optGroups[label];
|
|
2130
2712
|
},
|
|
2131
|
-
save: function
|
|
2132
|
-
|
|
2713
|
+
save: function () {
|
|
2714
|
+
const value = this.ui.select.val();
|
|
2715
|
+
if ('defaultValue' in this.options && value === this.options.defaultValue) {
|
|
2716
|
+
this.model.unset(this.options.propertyName);
|
|
2717
|
+
} else {
|
|
2718
|
+
this.model.set(this.options.propertyName, value);
|
|
2719
|
+
}
|
|
2133
2720
|
},
|
|
2134
|
-
load: function
|
|
2721
|
+
load: function () {
|
|
2135
2722
|
if (!this.isClosed) {
|
|
2136
2723
|
var value = this.model.get(this.options.propertyName);
|
|
2137
|
-
|
|
2138
2724
|
if (this.model.has(this.options.propertyName) && this.ui.select.find('option[value="' + value + '"]:not([disabled])').length) {
|
|
2139
2725
|
this.ui.select.val(value);
|
|
2726
|
+
} else if ('defaultValue' in this.options) {
|
|
2727
|
+
this.ui.select.val(this.options.defaultValue);
|
|
2140
2728
|
} else {
|
|
2141
2729
|
this.ui.select.val(this.ui.select.find('option:not([disabled]):first').val());
|
|
2142
2730
|
}
|
|
@@ -2144,11 +2732,10 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2144
2732
|
}
|
|
2145
2733
|
});
|
|
2146
2734
|
|
|
2147
|
-
|
|
2735
|
+
const ExtendedSelectInputView = SelectInputView.extend({
|
|
2148
2736
|
className: 'extended_select_input',
|
|
2149
|
-
initialize: function
|
|
2737
|
+
initialize: function () {
|
|
2150
2738
|
SelectInputView.prototype.initialize.apply(this, arguments);
|
|
2151
|
-
|
|
2152
2739
|
if (this.options.collection) {
|
|
2153
2740
|
if (this.options.descriptionProperty) {
|
|
2154
2741
|
this.options.descriptions = _.pluck(this.options.collection, this.options.descriptionProperty);
|
|
@@ -2156,47 +2743,42 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2156
2743
|
this.options.descriptionTanslationKeys = _.pluck(this.options.collection, this.options.descriptionTranslationKeyProperty);
|
|
2157
2744
|
}
|
|
2158
2745
|
}
|
|
2159
|
-
|
|
2160
2746
|
if (!this.options.descriptions) {
|
|
2161
2747
|
this.options.descriptions = _.map(this.options.descriptionTanslationKeys, function (key) {
|
|
2162
2748
|
return I18n$1.t(key);
|
|
2163
2749
|
});
|
|
2164
2750
|
}
|
|
2165
2751
|
},
|
|
2166
|
-
onRender: function
|
|
2752
|
+
onRender: function () {
|
|
2167
2753
|
var view = this,
|
|
2168
|
-
|
|
2754
|
+
options = this.options;
|
|
2169
2755
|
SelectInputView.prototype.onRender.apply(this, arguments);
|
|
2170
2756
|
$.widget("custom.extendedselectmenu", $.ui.selectmenu, {
|
|
2171
|
-
_renderItem: function
|
|
2757
|
+
_renderItem: function (ul, item) {
|
|
2172
2758
|
var widget = this;
|
|
2173
2759
|
var li = $('<li>', {
|
|
2174
|
-
|
|
2760
|
+
class: item.value
|
|
2175
2761
|
});
|
|
2176
2762
|
var container = $('<div>', {
|
|
2177
|
-
|
|
2763
|
+
class: 'text-container'
|
|
2178
2764
|
}).appendTo(li);
|
|
2179
2765
|
var index = options.values.indexOf(item.value);
|
|
2180
|
-
|
|
2181
2766
|
if (item.disabled) {
|
|
2182
2767
|
li.addClass('ui-state-disabled');
|
|
2183
2768
|
}
|
|
2184
|
-
|
|
2185
2769
|
if (options.pictogramClass) {
|
|
2186
2770
|
$('<span>', {
|
|
2187
|
-
|
|
2771
|
+
class: options.pictogramClass
|
|
2188
2772
|
}).prependTo(li);
|
|
2189
2773
|
}
|
|
2190
|
-
|
|
2191
2774
|
$('<p>', {
|
|
2192
2775
|
text: item.label,
|
|
2193
|
-
|
|
2776
|
+
class: 'item-text'
|
|
2194
2777
|
}).appendTo(container);
|
|
2195
2778
|
$('<p>', {
|
|
2196
2779
|
text: options.descriptions[index],
|
|
2197
|
-
|
|
2780
|
+
class: 'item-description'
|
|
2198
2781
|
}).appendTo(container);
|
|
2199
|
-
|
|
2200
2782
|
if (options.helpLinkClicked) {
|
|
2201
2783
|
$('<a>', {
|
|
2202
2784
|
href: '#',
|
|
@@ -2207,15 +2789,13 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2207
2789
|
return false;
|
|
2208
2790
|
}).appendTo(li);
|
|
2209
2791
|
}
|
|
2210
|
-
|
|
2211
2792
|
return li.appendTo(ul);
|
|
2212
2793
|
},
|
|
2213
|
-
_resizeMenu: function
|
|
2794
|
+
_resizeMenu: function () {
|
|
2214
2795
|
this.menuWrap.addClass('extended_select_input_menu');
|
|
2215
2796
|
var menuHeight = this.menu.height(),
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2797
|
+
menuOffset = this.button.offset().top + this.button.outerHeight(),
|
|
2798
|
+
bodyHeight = $('body').height();
|
|
2219
2799
|
if (menuHeight + menuOffset > bodyHeight) {
|
|
2220
2800
|
this.menuWrap.outerHeight(bodyHeight - menuOffset - 5).css({
|
|
2221
2801
|
'overflow-y': 'scroll'
|
|
@@ -2237,13 +2817,13 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2237
2817
|
}
|
|
2238
2818
|
});
|
|
2239
2819
|
},
|
|
2240
|
-
select: function
|
|
2820
|
+
select: function (event, ui) {
|
|
2241
2821
|
this.ui.select.val(ui.item.value);
|
|
2242
2822
|
this.save();
|
|
2243
2823
|
}
|
|
2244
2824
|
});
|
|
2245
2825
|
|
|
2246
|
-
function template$
|
|
2826
|
+
function template$a(data) {
|
|
2247
2827
|
var __t, __p = '';
|
|
2248
2828
|
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<!-- inline style for wysihtml5 to pick up -->\n<textarea style="width: 100%;" dir="auto"></textarea>\n\n<div class="toolbar">\n <a data-wysihtml5-command="bold" title="' +
|
|
2249
2829
|
((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.bold') )) == null ? '' : __t) +
|
|
@@ -2300,10 +2880,9 @@ return __p
|
|
|
2300
2880
|
*
|
|
2301
2881
|
* @class
|
|
2302
2882
|
*/
|
|
2303
|
-
|
|
2304
|
-
var TextAreaInputView = Marionette.ItemView.extend({
|
|
2883
|
+
const TextAreaInputView = Marionette.ItemView.extend({
|
|
2305
2884
|
mixins: [inputView, inputWithPlaceholderText],
|
|
2306
|
-
template: template$
|
|
2885
|
+
template: template$a,
|
|
2307
2886
|
className: 'text_area_input',
|
|
2308
2887
|
ui: {
|
|
2309
2888
|
input: 'textarea',
|
|
@@ -2327,7 +2906,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2327
2906
|
'change .open_in_new_tab': 'setTargetFromOpenInNewTabCheckBox',
|
|
2328
2907
|
'change .display_url': 'setUrlFromDisplayUrl'
|
|
2329
2908
|
},
|
|
2330
|
-
onRender: function
|
|
2909
|
+
onRender: function () {
|
|
2331
2910
|
this.ui.input.addClass(this.options.size);
|
|
2332
2911
|
this.load();
|
|
2333
2912
|
this.updatePlaceholder();
|
|
@@ -2376,7 +2955,6 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2376
2955
|
}
|
|
2377
2956
|
}
|
|
2378
2957
|
});
|
|
2379
|
-
|
|
2380
2958
|
if (this.options.disableRichtext) {
|
|
2381
2959
|
this.ui.toolbar.find('a[data-wysihtml5-command="bold"]').hide();
|
|
2382
2960
|
this.ui.toolbar.find('a[data-wysihtml5-command="italic"]').hide();
|
|
@@ -2384,36 +2962,42 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2384
2962
|
this.ui.toolbar.find('a[data-wysihtml5-command="insertOrderedList"]').hide();
|
|
2385
2963
|
this.ui.toolbar.find('a[data-wysihtml5-command="insertUnorderedList"]').hide();
|
|
2386
2964
|
}
|
|
2387
|
-
|
|
2388
2965
|
if (!this.options.enableLists) {
|
|
2389
2966
|
this.ui.toolbar.find('a[data-wysihtml5-command="insertOrderedList"]').hide();
|
|
2390
2967
|
this.ui.toolbar.find('a[data-wysihtml5-command="insertUnorderedList"]').hide();
|
|
2391
2968
|
}
|
|
2392
|
-
|
|
2393
2969
|
if (this.options.disableLinks) {
|
|
2394
2970
|
this.ui.toolbar.find('a[data-wysihtml5-command="createLink"]').hide();
|
|
2395
2971
|
} else {
|
|
2396
2972
|
this.setupUrlLinkPanel();
|
|
2397
2973
|
this.setupFragmentLinkPanel();
|
|
2398
2974
|
}
|
|
2399
|
-
|
|
2400
2975
|
this.editor.on('change', _.bind(this.save, this));
|
|
2401
2976
|
this.editor.on('aftercommand:composer', _.bind(this.save, this));
|
|
2402
2977
|
},
|
|
2403
|
-
onClose: function
|
|
2978
|
+
onClose: function () {
|
|
2404
2979
|
this.editor.fire('destroy:composer');
|
|
2405
2980
|
},
|
|
2406
|
-
|
|
2981
|
+
updateDisabled: function () {
|
|
2982
|
+
inputView.updateDisabled.call(this);
|
|
2983
|
+
if (this.isDisabled()) {
|
|
2984
|
+
this.editor.disable();
|
|
2985
|
+
this.$el.attr('inert', true);
|
|
2986
|
+
} else {
|
|
2987
|
+
this.editor.enable();
|
|
2988
|
+
this.$el.removeAttr('inert');
|
|
2989
|
+
}
|
|
2990
|
+
},
|
|
2991
|
+
save: function () {
|
|
2407
2992
|
this.model.set(this.options.propertyName, this.editor.getValue());
|
|
2408
2993
|
},
|
|
2409
|
-
load: function
|
|
2994
|
+
load: function () {
|
|
2410
2995
|
this.ui.input.val(this.model.get(this.options.propertyName));
|
|
2411
2996
|
},
|
|
2412
|
-
setupUrlLinkPanel: function
|
|
2997
|
+
setupUrlLinkPanel: function () {
|
|
2413
2998
|
this.editor.on('show:dialog', _.bind(function () {
|
|
2414
2999
|
this.ui.linkDialog.toggleClass('for_existing_link', this.ui.linkButton.hasClass('wysihtml5-command-active'));
|
|
2415
3000
|
var currentUrl = this.ui.urlInput.val();
|
|
2416
|
-
|
|
2417
3001
|
if (currentUrl.startsWith('#')) {
|
|
2418
3002
|
this.ui.displayUrlInput.val('');
|
|
2419
3003
|
this.ui.openInNewTabCheckBox.prop('checked', true);
|
|
@@ -2423,7 +3007,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2423
3007
|
}
|
|
2424
3008
|
}, this));
|
|
2425
3009
|
},
|
|
2426
|
-
setupFragmentLinkPanel: function
|
|
3010
|
+
setupFragmentLinkPanel: function () {
|
|
2427
3011
|
if (this.options.fragmentLinkInputView) {
|
|
2428
3012
|
this.fragmentLinkModel = new Backbone.Model();
|
|
2429
3013
|
this.listenTo(this.fragmentLinkModel, 'change', function (model, options) {
|
|
@@ -2451,37 +3035,36 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2451
3035
|
this.ui.fragmentLinkPanel.hide();
|
|
2452
3036
|
}
|
|
2453
3037
|
},
|
|
2454
|
-
initLinkTypePanels: function
|
|
3038
|
+
initLinkTypePanels: function (isUrlLink) {
|
|
2455
3039
|
if (isUrlLink) {
|
|
2456
3040
|
this.ui.urlLinkRadioButton.prop('checked', true);
|
|
2457
3041
|
} else {
|
|
2458
3042
|
this.ui.fragmentLinkRadioButton.prop('checked', true);
|
|
2459
3043
|
}
|
|
2460
|
-
|
|
2461
3044
|
this.ui.toolbar.toggleClass('fragment_link_panel_active', !isUrlLink);
|
|
2462
3045
|
},
|
|
2463
|
-
showUrlLinkPanel: function
|
|
3046
|
+
showUrlLinkPanel: function () {
|
|
2464
3047
|
this.ui.toolbar.removeClass('fragment_link_panel_active');
|
|
2465
3048
|
this.setUrlFromDisplayUrl();
|
|
2466
3049
|
this.setTargetFromOpenInNewTabCheckBox();
|
|
2467
3050
|
},
|
|
2468
|
-
showFragmentLinkPanel: function
|
|
3051
|
+
showFragmentLinkPanel: function () {
|
|
2469
3052
|
this.ui.toolbar.addClass('fragment_link_panel_active');
|
|
2470
3053
|
this.setInputsFromFragmentLinkModel();
|
|
2471
3054
|
},
|
|
2472
|
-
setInputsFromFragmentLinkModel: function
|
|
3055
|
+
setInputsFromFragmentLinkModel: function () {
|
|
2473
3056
|
this.ui.urlInput.val('#' + (this.fragmentLinkModel.get('linkId') || ''));
|
|
2474
3057
|
this.ui.targetInput.val('_self');
|
|
2475
3058
|
},
|
|
2476
|
-
setUrlFromDisplayUrl: function
|
|
3059
|
+
setUrlFromDisplayUrl: function () {
|
|
2477
3060
|
this.ui.urlInput.val(this.ui.displayUrlInput.val());
|
|
2478
3061
|
},
|
|
2479
|
-
setTargetFromOpenInNewTabCheckBox: function
|
|
3062
|
+
setTargetFromOpenInNewTabCheckBox: function () {
|
|
2480
3063
|
this.ui.targetInput.val(this.ui.openInNewTabCheckBox.is(':checked') ? '_blank' : '_self');
|
|
2481
3064
|
}
|
|
2482
3065
|
});
|
|
2483
3066
|
|
|
2484
|
-
function template$
|
|
3067
|
+
function template$b(data) {
|
|
2485
3068
|
var __p = '';
|
|
2486
3069
|
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" />\n<div class="validation"></div>\n';
|
|
2487
3070
|
return __p
|
|
@@ -2504,12 +3087,9 @@ return __p
|
|
|
2504
3087
|
*
|
|
2505
3088
|
* @class
|
|
2506
3089
|
*/
|
|
2507
|
-
|
|
2508
|
-
var UrlInputView = Marionette.Layout.extend(
|
|
2509
|
-
/** @lends UrlInputView.prototype */
|
|
2510
|
-
{
|
|
3090
|
+
const UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype */{
|
|
2511
3091
|
mixins: [inputView],
|
|
2512
|
-
template: template$
|
|
3092
|
+
template: template$b,
|
|
2513
3093
|
ui: {
|
|
2514
3094
|
input: 'input',
|
|
2515
3095
|
validation: '.validation'
|
|
@@ -2517,95 +3097,95 @@ var UrlInputView = Marionette.Layout.extend(
|
|
|
2517
3097
|
events: {
|
|
2518
3098
|
'change': 'onChange'
|
|
2519
3099
|
},
|
|
2520
|
-
onRender: function
|
|
3100
|
+
onRender: function () {
|
|
2521
3101
|
this.ui.validation.hide();
|
|
2522
3102
|
this.load();
|
|
2523
3103
|
this.validate();
|
|
3104
|
+
this.listenTo(this.model, 'change:' + this.options.displayPropertyName, this.load);
|
|
2524
3105
|
},
|
|
2525
|
-
onChange: function
|
|
2526
|
-
var
|
|
2527
|
-
|
|
2528
|
-
this.validate().then(function () {
|
|
2529
|
-
return _this.save();
|
|
2530
|
-
}, function () {
|
|
2531
|
-
return _this.saveDisplayProperty();
|
|
2532
|
-
});
|
|
3106
|
+
onChange: function () {
|
|
3107
|
+
var value = this.ui.input.val();
|
|
3108
|
+
this.validate().then(() => this.save(value), () => this.saveDisplayProperty(value));
|
|
2533
3109
|
},
|
|
2534
|
-
saveDisplayProperty: function
|
|
3110
|
+
saveDisplayProperty: function (value) {
|
|
2535
3111
|
this.model.unset(this.options.propertyName, {
|
|
2536
3112
|
silent: true
|
|
2537
3113
|
});
|
|
2538
|
-
this.model.set(this.options.displayPropertyName,
|
|
3114
|
+
this.model.set(this.options.displayPropertyName, value);
|
|
2539
3115
|
},
|
|
2540
|
-
save: function
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
_this2.model.set((_this2$model$set = {}, _defineProperty(_this2$model$set, _this2.options.displayPropertyName, value), _defineProperty(_this2$model$set, _this2.options.propertyName, transformedValue), _this2$model$set));
|
|
3116
|
+
save: function (value) {
|
|
3117
|
+
$.when(this.transformPropertyValue(value, this.lastValidationResult)).then(transformedValue => {
|
|
3118
|
+
this.model.set({
|
|
3119
|
+
[this.options.displayPropertyName]: value,
|
|
3120
|
+
[this.options.propertyName]: transformedValue
|
|
3121
|
+
});
|
|
2548
3122
|
});
|
|
2549
3123
|
},
|
|
2550
|
-
load: function
|
|
3124
|
+
load: function () {
|
|
2551
3125
|
this.ui.input.val(this.model.has(this.options.displayPropertyName) ? this.model.get(this.options.displayPropertyName) : this.model.get(this.options.propertyName));
|
|
2552
3126
|
this.onLoad();
|
|
2553
3127
|
},
|
|
2554
|
-
|
|
2555
3128
|
/**
|
|
2556
3129
|
* Override to be notified when the input has been loaded.
|
|
2557
3130
|
*/
|
|
2558
|
-
onLoad: function
|
|
2559
|
-
|
|
3131
|
+
onLoad: function () {},
|
|
2560
3132
|
/**
|
|
2561
3133
|
* Override to validate the untransformed url. Validation error
|
|
2562
3134
|
* message can be passed as rejected promise. Progress notifications
|
|
2563
3135
|
* are displayed. Only valid urls are stored in the configuration.
|
|
2564
3136
|
*
|
|
3137
|
+
* Can optionally return a value when the promise resolves. This
|
|
3138
|
+
* value will be passed to transformPropertyValue as the second
|
|
3139
|
+
* parameter.
|
|
3140
|
+
*
|
|
2565
3141
|
* @return Promise
|
|
2566
3142
|
*/
|
|
2567
|
-
validateUrl: function
|
|
3143
|
+
validateUrl: function (url) {
|
|
2568
3144
|
return $.Deferred().resolve().promise();
|
|
2569
3145
|
},
|
|
2570
|
-
|
|
2571
3146
|
/**
|
|
2572
3147
|
* Override to transform the property value before it is stored.
|
|
2573
3148
|
*
|
|
3149
|
+
* @param {String} value - The URL value to transform
|
|
3150
|
+
* @param {*} validationResult - Optional result returned by validateUrl
|
|
2574
3151
|
* @return Promise | String
|
|
2575
3152
|
*/
|
|
2576
|
-
transformPropertyValue: function
|
|
3153
|
+
transformPropertyValue: function (value, validationResult) {
|
|
2577
3154
|
return value;
|
|
2578
3155
|
},
|
|
2579
|
-
|
|
2580
3156
|
/**
|
|
2581
3157
|
* Override to change the list of supported host names.
|
|
2582
3158
|
*/
|
|
2583
|
-
supportedHosts: function
|
|
3159
|
+
supportedHosts: function () {
|
|
2584
3160
|
return this.options.supportedHosts;
|
|
2585
3161
|
},
|
|
3162
|
+
/**
|
|
3163
|
+
* Override to enable HTTPS URLs by default.
|
|
3164
|
+
* @return {boolean}
|
|
3165
|
+
*/
|
|
3166
|
+
permitHttps: function () {
|
|
3167
|
+
return this.options.permitHttps;
|
|
3168
|
+
},
|
|
2586
3169
|
// Host names used to be expected to include protocols. Remove
|
|
2587
3170
|
// protocols for backwards compatilbity. Since supportedHosts
|
|
2588
3171
|
// is supposed to be overridden in subclasses, we do it in a
|
|
2589
3172
|
// separate method.
|
|
2590
|
-
supportedHostsWithoutLegacyProtocols: function
|
|
3173
|
+
supportedHostsWithoutLegacyProtocols: function () {
|
|
2591
3174
|
return _.map(this.supportedHosts(), function (host) {
|
|
2592
3175
|
return host.replace(/^https?:\/\//, '');
|
|
2593
3176
|
});
|
|
2594
3177
|
},
|
|
2595
|
-
validate: function
|
|
3178
|
+
validate: function (success) {
|
|
2596
3179
|
var view = this;
|
|
2597
3180
|
var options = this.options;
|
|
2598
3181
|
var value = this.ui.input.val();
|
|
2599
|
-
|
|
2600
3182
|
if (options.required && !value) {
|
|
2601
3183
|
displayValidationError(I18n$1.t('pageflow.ui.views.inputs.url_input_view.required_field'));
|
|
2602
3184
|
} else if (value && !isValidUrl(value)) {
|
|
2603
3185
|
var errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint');
|
|
2604
|
-
|
|
2605
|
-
if (options.permitHttps) {
|
|
3186
|
+
if (view.permitHttps()) {
|
|
2606
3187
|
errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint_https');
|
|
2607
3188
|
}
|
|
2608
|
-
|
|
2609
3189
|
displayValidationError(errorMessage);
|
|
2610
3190
|
} else if (value && !hasSupportedHost(value)) {
|
|
2611
3191
|
displayValidationError(I18n$1.t('pageflow.ui.views.inputs.url_input_view.supported_vendors') + _.map(view.supportedHosts(), function (url) {
|
|
@@ -2613,41 +3193,44 @@ var UrlInputView = Marionette.Layout.extend(
|
|
|
2613
3193
|
}).join(''));
|
|
2614
3194
|
} else {
|
|
2615
3195
|
return view.validateUrl(value).progress(function (message) {
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
3196
|
+
if (!view.isClosed) {
|
|
3197
|
+
displayValidationPending(message);
|
|
3198
|
+
}
|
|
3199
|
+
}).done(function (result) {
|
|
3200
|
+
view.lastValidationResult = result;
|
|
3201
|
+
if (!view.isClosed) {
|
|
3202
|
+
resetValidationError();
|
|
3203
|
+
}
|
|
2619
3204
|
}).fail(function (error) {
|
|
2620
|
-
|
|
3205
|
+
view.lastValidationResult = undefined;
|
|
3206
|
+
if (!view.isClosed) {
|
|
3207
|
+
displayValidationError(error);
|
|
3208
|
+
}
|
|
2621
3209
|
});
|
|
2622
3210
|
}
|
|
2623
|
-
|
|
2624
3211
|
return $.Deferred().reject().promise();
|
|
2625
|
-
|
|
2626
3212
|
function isValidUrl(url) {
|
|
2627
|
-
return
|
|
3213
|
+
return view.permitHttps() ? url.match(/^https?:\/\//i) : url.match(/^http:\/\//i);
|
|
2628
3214
|
}
|
|
2629
|
-
|
|
2630
3215
|
function hasSupportedHost(url) {
|
|
2631
3216
|
return _.any(view.supportedHostsWithoutLegacyProtocols(), function (host) {
|
|
2632
3217
|
return url.match(new RegExp('^https?://' + host));
|
|
2633
3218
|
});
|
|
2634
3219
|
}
|
|
2635
|
-
|
|
2636
3220
|
function displayValidationError(message) {
|
|
2637
3221
|
view.$el.addClass('invalid');
|
|
2638
3222
|
view.ui.input.attr('aria-invalid', 'true');
|
|
2639
3223
|
view.ui.validation.removeClass('pending').addClass('failed').html(message).show();
|
|
2640
3224
|
}
|
|
2641
|
-
|
|
2642
3225
|
function displayValidationPending(message) {
|
|
2643
3226
|
view.$el.removeClass('invalid');
|
|
2644
3227
|
view.ui.input.removeAttr('aria-invalid');
|
|
2645
3228
|
view.ui.validation.removeClass('failed').addClass('pending').html(message).show();
|
|
2646
3229
|
}
|
|
2647
|
-
|
|
2648
3230
|
function resetValidationError(message) {
|
|
2649
3231
|
view.$el.removeClass('invalid');
|
|
2650
3232
|
view.ui.input.attr('aria-invalid', 'false');
|
|
3233
|
+
view.ui.validation.text('');
|
|
2651
3234
|
view.ui.validation.hide();
|
|
2652
3235
|
}
|
|
2653
3236
|
}
|
|
@@ -2699,12 +3282,9 @@ var UrlInputView = Marionette.Layout.extend(
|
|
|
2699
3282
|
*
|
|
2700
3283
|
* @class
|
|
2701
3284
|
*/
|
|
2702
|
-
|
|
2703
|
-
var ProxyUrlInputView = UrlInputView.extend(
|
|
2704
|
-
/** @lends ProxyUrlInputView.prototype */
|
|
2705
|
-
{
|
|
3285
|
+
const ProxyUrlInputView = UrlInputView.extend( /** @lends ProxyUrlInputView.prototype */{
|
|
2706
3286
|
// @override
|
|
2707
|
-
validateUrl: function
|
|
3287
|
+
validateUrl: function (url) {
|
|
2708
3288
|
var view = this;
|
|
2709
3289
|
return $.Deferred(function (deferred) {
|
|
2710
3290
|
deferred.notify(I18n$1.t('pageflow.ui.views.inputs.proxy_url_input_view.url_validation'));
|
|
@@ -2719,25 +3299,28 @@ var ProxyUrlInputView = UrlInputView.extend(
|
|
|
2719
3299
|
}).promise();
|
|
2720
3300
|
},
|
|
2721
3301
|
// override
|
|
2722
|
-
transformPropertyValue: function
|
|
3302
|
+
transformPropertyValue: function (url) {
|
|
2723
3303
|
return this.rewriteUrl(url);
|
|
2724
3304
|
},
|
|
2725
3305
|
// override
|
|
2726
|
-
supportedHosts: function
|
|
3306
|
+
supportedHosts: function () {
|
|
2727
3307
|
return _.pluck(this.options.proxies, 'url');
|
|
2728
3308
|
},
|
|
2729
|
-
rewriteUrl: function
|
|
3309
|
+
rewriteUrl: function (url) {
|
|
2730
3310
|
_.each(this.options.proxies, function (proxy) {
|
|
2731
3311
|
url = url.replace(new RegExp('^' + proxy.url + '/?'), proxy.base_path + '/');
|
|
2732
3312
|
});
|
|
2733
|
-
|
|
2734
3313
|
return url;
|
|
2735
3314
|
}
|
|
2736
3315
|
});
|
|
2737
3316
|
|
|
2738
|
-
function template$
|
|
2739
|
-
var __p = '';
|
|
2740
|
-
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="
|
|
3317
|
+
function template$c(data) {
|
|
3318
|
+
var __t, __p = '';
|
|
3319
|
+
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="slider_wrapper">\n ';
|
|
3320
|
+
if (data.icon) {__p += '<img class="icon" src="' +
|
|
3321
|
+
((__t = ( data.icon )) == null ? '' : __t) +
|
|
3322
|
+
'" width="18" height="18" />';
|
|
3323
|
+
}__p += '\n <div class="value"></div>\n <div class="slider"></div>\n</div>\n';
|
|
2741
3324
|
return __p
|
|
2742
3325
|
}
|
|
2743
3326
|
|
|
@@ -2748,7 +3331,7 @@ return __p
|
|
|
2748
3331
|
* @param {Object} [options]
|
|
2749
3332
|
*
|
|
2750
3333
|
* @param {number} [options.defaultValue]
|
|
2751
|
-
*
|
|
3334
|
+
* Default value to display if property is not set.
|
|
2752
3335
|
*
|
|
2753
3336
|
* @param {number} [options.minValue=0]
|
|
2754
3337
|
* Value when dragging slider to the very left.
|
|
@@ -2766,92 +3349,116 @@ return __p
|
|
|
2766
3349
|
* Already update the model while dragging the handle - not only after
|
|
2767
3350
|
* handle has been released.
|
|
2768
3351
|
*
|
|
3352
|
+
* @param {string} [options.icon]
|
|
3353
|
+
* Path to an icon image to display before the label.
|
|
3354
|
+
*
|
|
2769
3355
|
* @class
|
|
2770
3356
|
*/
|
|
2771
|
-
|
|
2772
|
-
var SliderInputView = Marionette.ItemView.extend({
|
|
3357
|
+
const SliderInputView = Marionette.ItemView.extend({
|
|
2773
3358
|
mixins: [inputView],
|
|
2774
3359
|
className: 'slider_input',
|
|
2775
|
-
template: template$
|
|
3360
|
+
template: template$c,
|
|
3361
|
+
serializeData() {
|
|
3362
|
+
return {
|
|
3363
|
+
icon: this.options.icon
|
|
3364
|
+
};
|
|
3365
|
+
},
|
|
2776
3366
|
ui: {
|
|
2777
3367
|
widget: '.slider',
|
|
2778
3368
|
value: '.value'
|
|
2779
3369
|
},
|
|
2780
3370
|
events: {
|
|
3371
|
+
'slidestart': 'handleSlideStart',
|
|
2781
3372
|
'slidechange': 'save',
|
|
2782
3373
|
'slide': 'handleSlide'
|
|
2783
3374
|
},
|
|
2784
|
-
onRender: function
|
|
2785
|
-
var _this = this;
|
|
2786
|
-
|
|
3375
|
+
onRender: function () {
|
|
2787
3376
|
this.ui.widget.slider({
|
|
2788
3377
|
animate: 'fast'
|
|
2789
3378
|
});
|
|
2790
|
-
this.
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
3379
|
+
if (this.options.values) {
|
|
3380
|
+
this.ui.widget.slider('option', 'min', 0);
|
|
3381
|
+
this.ui.widget.slider('option', 'max', this.options.values.length - 1);
|
|
3382
|
+
} else {
|
|
3383
|
+
this.setupAttributeBinding('minValue', value => this.updateSliderOption('min', value || 0));
|
|
3384
|
+
this.setupAttributeBinding('maxValue', value => this.updateSliderOption('max', value !== undefined ? value : 100));
|
|
3385
|
+
}
|
|
2796
3386
|
this.load();
|
|
2797
3387
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2798
3388
|
},
|
|
2799
|
-
updateSliderOption
|
|
3389
|
+
updateSliderOption(name, value) {
|
|
2800
3390
|
this.ui.widget.slider('option', name, value);
|
|
2801
3391
|
this.updateText(this.ui.widget.slider('value'));
|
|
2802
3392
|
},
|
|
2803
|
-
updateDisabled: function
|
|
3393
|
+
updateDisabled: function (disabled) {
|
|
2804
3394
|
this.$el.toggleClass('disabled', !!disabled);
|
|
2805
|
-
|
|
2806
3395
|
if (disabled) {
|
|
2807
3396
|
this.ui.widget.slider('disable');
|
|
2808
3397
|
} else {
|
|
2809
3398
|
this.ui.widget.slider('enable');
|
|
2810
3399
|
}
|
|
2811
3400
|
},
|
|
2812
|
-
|
|
2813
|
-
this.
|
|
2814
|
-
|
|
3401
|
+
handleSlideStart() {
|
|
3402
|
+
if (this.options.onInteractionStart) {
|
|
3403
|
+
this.options.onInteractionStart();
|
|
3404
|
+
}
|
|
3405
|
+
},
|
|
3406
|
+
handleSlide(event, ui) {
|
|
3407
|
+
var value = this.options.values ? this.options.values[ui.value] : ui.value;
|
|
3408
|
+
this.updateText(value);
|
|
2815
3409
|
if (this.options.saveOnSlide) {
|
|
2816
3410
|
this.save(event, ui);
|
|
2817
3411
|
}
|
|
2818
3412
|
},
|
|
2819
|
-
save: function
|
|
2820
|
-
|
|
3413
|
+
save: function (event, ui) {
|
|
3414
|
+
if (this.loading) {
|
|
3415
|
+
return;
|
|
3416
|
+
}
|
|
3417
|
+
var value = this.options.values ? this.options.values[ui.value] : ui.value;
|
|
3418
|
+
this.model.set(this.options.propertyName, value);
|
|
2821
3419
|
},
|
|
2822
|
-
load: function
|
|
3420
|
+
load: function () {
|
|
2823
3421
|
var value;
|
|
2824
|
-
|
|
2825
3422
|
if (this.model.has(this.options.propertyName)) {
|
|
2826
3423
|
value = this.model.get(this.options.propertyName);
|
|
2827
3424
|
} else {
|
|
2828
3425
|
value = 'defaultValue' in this.options ? this.options.defaultValue : 0;
|
|
2829
3426
|
}
|
|
2830
|
-
|
|
2831
|
-
this.
|
|
3427
|
+
var sliderValue = this.options.values ? this.options.values.indexOf(value) : value;
|
|
3428
|
+
this.loading = true;
|
|
3429
|
+
this.ui.widget.slider('option', 'value', this.clampValue(sliderValue));
|
|
3430
|
+
this.loading = false;
|
|
2832
3431
|
this.updateText(value);
|
|
2833
3432
|
},
|
|
2834
|
-
clampValue
|
|
2835
|
-
|
|
2836
|
-
|
|
3433
|
+
clampValue(value) {
|
|
3434
|
+
const min = this.ui.widget.slider('option', 'min');
|
|
3435
|
+
const max = this.ui.widget.slider('option', 'max');
|
|
2837
3436
|
return Math.min(max, Math.max(min, value));
|
|
2838
3437
|
},
|
|
2839
|
-
updateText: function
|
|
2840
|
-
var
|
|
2841
|
-
|
|
3438
|
+
updateText: function (value) {
|
|
3439
|
+
var text;
|
|
3440
|
+
if (this.options.texts) {
|
|
3441
|
+
var index = this.options.values.indexOf(value);
|
|
3442
|
+
text = this.options.texts[index];
|
|
3443
|
+
} else if ('displayText' in this.options) {
|
|
3444
|
+
text = this.options.displayText(value);
|
|
3445
|
+
} else {
|
|
3446
|
+
var unit = 'unit' in this.options ? this.options.unit : '%';
|
|
3447
|
+
text = value + unit;
|
|
3448
|
+
}
|
|
2842
3449
|
this.ui.value.text(text);
|
|
2843
3450
|
}
|
|
2844
3451
|
});
|
|
2845
3452
|
|
|
2846
|
-
function template$
|
|
3453
|
+
function template$d(data) {
|
|
2847
3454
|
var __p = '';
|
|
2848
3455
|
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<textarea></textarea>\n';
|
|
2849
3456
|
return __p
|
|
2850
3457
|
}
|
|
2851
3458
|
|
|
2852
|
-
|
|
3459
|
+
const JsonInputView = Marionette.ItemView.extend({
|
|
2853
3460
|
mixins: [inputView],
|
|
2854
|
-
template: template$
|
|
3461
|
+
template: template$d,
|
|
2855
3462
|
className: 'json_input',
|
|
2856
3463
|
ui: {
|
|
2857
3464
|
input: 'textarea'
|
|
@@ -2860,32 +3467,31 @@ var JsonInputView = Marionette.ItemView.extend({
|
|
|
2860
3467
|
'change': 'onChange',
|
|
2861
3468
|
'keyup': 'validate'
|
|
2862
3469
|
},
|
|
2863
|
-
onRender: function
|
|
3470
|
+
onRender: function () {
|
|
2864
3471
|
this.load();
|
|
2865
3472
|
this.validate();
|
|
2866
3473
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2867
3474
|
},
|
|
2868
|
-
onChange: function
|
|
3475
|
+
onChange: function () {
|
|
2869
3476
|
if (this.validate()) {
|
|
2870
3477
|
this.save();
|
|
2871
3478
|
}
|
|
2872
3479
|
},
|
|
2873
|
-
onClose: function
|
|
3480
|
+
onClose: function () {
|
|
2874
3481
|
if (this.validate()) {
|
|
2875
3482
|
this.save();
|
|
2876
3483
|
}
|
|
2877
3484
|
},
|
|
2878
|
-
save: function
|
|
3485
|
+
save: function () {
|
|
2879
3486
|
this.model.set(this.options.propertyName, this.ui.input.val() ? JSON.parse(this.ui.input.val()) : null);
|
|
2880
3487
|
},
|
|
2881
|
-
load: function
|
|
3488
|
+
load: function () {
|
|
2882
3489
|
var input = this.ui.input;
|
|
2883
3490
|
var value = this.model.get(this.options.propertyName);
|
|
2884
3491
|
input.val(value ? JSON.stringify(value, null, 2) : '');
|
|
2885
3492
|
},
|
|
2886
|
-
validate: function
|
|
3493
|
+
validate: function () {
|
|
2887
3494
|
var input = this.ui.input;
|
|
2888
|
-
|
|
2889
3495
|
if (input.val() && !this.isValidJson(input.val())) {
|
|
2890
3496
|
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.json_input_view.invalid'));
|
|
2891
3497
|
return false;
|
|
@@ -2894,15 +3500,15 @@ var JsonInputView = Marionette.ItemView.extend({
|
|
|
2894
3500
|
return true;
|
|
2895
3501
|
}
|
|
2896
3502
|
},
|
|
2897
|
-
displayValidationError: function
|
|
3503
|
+
displayValidationError: function (message) {
|
|
2898
3504
|
this.$el.addClass('invalid');
|
|
2899
3505
|
this.ui.input.attr('title', message);
|
|
2900
3506
|
},
|
|
2901
|
-
resetValidationError: function
|
|
3507
|
+
resetValidationError: function (message) {
|
|
2902
3508
|
this.$el.removeClass('invalid');
|
|
2903
3509
|
this.ui.input.attr('title', '');
|
|
2904
3510
|
},
|
|
2905
|
-
isValidJson: function
|
|
3511
|
+
isValidJson: function (text) {
|
|
2906
3512
|
try {
|
|
2907
3513
|
JSON.parse(text);
|
|
2908
3514
|
return true;
|
|
@@ -2912,7 +3518,7 @@ var JsonInputView = Marionette.ItemView.extend({
|
|
|
2912
3518
|
}
|
|
2913
3519
|
});
|
|
2914
3520
|
|
|
2915
|
-
function template$
|
|
3521
|
+
function template$e(data) {
|
|
2916
3522
|
var __p = '';
|
|
2917
3523
|
__p += '<input type="checkbox" />\n<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>';
|
|
2918
3524
|
return __p
|
|
@@ -2939,10 +3545,9 @@ return __p
|
|
|
2939
3545
|
*
|
|
2940
3546
|
* @class
|
|
2941
3547
|
*/
|
|
2942
|
-
|
|
2943
|
-
var CheckBoxInputView = Marionette.ItemView.extend({
|
|
3548
|
+
const CheckBoxInputView = Marionette.ItemView.extend({
|
|
2944
3549
|
mixins: [inputView],
|
|
2945
|
-
template: template$
|
|
3550
|
+
template: template$e,
|
|
2946
3551
|
className: 'check_box_input',
|
|
2947
3552
|
events: {
|
|
2948
3553
|
'change': 'save'
|
|
@@ -2951,19 +3556,18 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2951
3556
|
input: 'input',
|
|
2952
3557
|
label: 'label'
|
|
2953
3558
|
},
|
|
2954
|
-
onRender: function
|
|
3559
|
+
onRender: function () {
|
|
2955
3560
|
this.ui.label.attr('for', this.cid);
|
|
2956
3561
|
this.ui.input.attr('id', this.cid);
|
|
2957
3562
|
this.load();
|
|
2958
3563
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2959
3564
|
},
|
|
2960
|
-
updateDisabled: function
|
|
3565
|
+
updateDisabled: function () {
|
|
2961
3566
|
this.load();
|
|
2962
3567
|
},
|
|
2963
|
-
save: function
|
|
3568
|
+
save: function () {
|
|
2964
3569
|
if (!this.isDisabled()) {
|
|
2965
|
-
|
|
2966
|
-
|
|
3570
|
+
const value = this.ui.input.is(':checked');
|
|
2967
3571
|
if (this.options.storeInverted) {
|
|
2968
3572
|
this.model.set(this.options.storeInverted, !value);
|
|
2969
3573
|
} else {
|
|
@@ -2971,12 +3575,12 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2971
3575
|
}
|
|
2972
3576
|
}
|
|
2973
3577
|
},
|
|
2974
|
-
load: function
|
|
3578
|
+
load: function () {
|
|
2975
3579
|
if (!this.isClosed) {
|
|
2976
|
-
this.ui.input.prop('checked', this.displayValue());
|
|
3580
|
+
this.ui.input.prop('checked', !!this.displayValue());
|
|
2977
3581
|
}
|
|
2978
3582
|
},
|
|
2979
|
-
displayValue: function
|
|
3583
|
+
displayValue: function () {
|
|
2980
3584
|
if (this.isDisabled() && this.options.displayUncheckedIfDisabled) {
|
|
2981
3585
|
return false;
|
|
2982
3586
|
} else if (this.isDisabled() && this.options.displayCheckedIfDisabled) {
|
|
@@ -2989,6 +3593,86 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2989
3593
|
}
|
|
2990
3594
|
});
|
|
2991
3595
|
|
|
3596
|
+
/**
|
|
3597
|
+
* Input view for selecting one value from a small set of options
|
|
3598
|
+
* using radio buttons.
|
|
3599
|
+
* See {@link inputView} for further options.
|
|
3600
|
+
*
|
|
3601
|
+
* @param {Object} [options]
|
|
3602
|
+
*
|
|
3603
|
+
* @param {Array} options.values
|
|
3604
|
+
* Array of possible values the property can be set to.
|
|
3605
|
+
*
|
|
3606
|
+
* @param {Array} [options.texts]
|
|
3607
|
+
* Array of display texts for the values. If not provided,
|
|
3608
|
+
* translations are looked up based on the model's i18nKey.
|
|
3609
|
+
*
|
|
3610
|
+
* @class
|
|
3611
|
+
*/
|
|
3612
|
+
const RadioButtonGroupInputView = Marionette.ItemView.extend({
|
|
3613
|
+
mixins: [inputView],
|
|
3614
|
+
template: () => `
|
|
3615
|
+
<label>
|
|
3616
|
+
<span class="name"></span>
|
|
3617
|
+
<span class="inline_help"></span>
|
|
3618
|
+
</label>
|
|
3619
|
+
`,
|
|
3620
|
+
className: 'radio_button_input',
|
|
3621
|
+
events: {
|
|
3622
|
+
'change': 'save'
|
|
3623
|
+
},
|
|
3624
|
+
initialize: function () {
|
|
3625
|
+
if (!this.options.texts) {
|
|
3626
|
+
var translationKeyPrefix = findKeyWithTranslation(this.attributeTranslationKeys('values', {
|
|
3627
|
+
fallbackPrefix: 'activerecord.values'
|
|
3628
|
+
}));
|
|
3629
|
+
this.options.texts = _.map(this.options.values, function (value) {
|
|
3630
|
+
return I18n$1.t(translationKeyPrefix + '.' + value);
|
|
3631
|
+
});
|
|
3632
|
+
}
|
|
3633
|
+
},
|
|
3634
|
+
onRender: function () {
|
|
3635
|
+
this.appendOptions();
|
|
3636
|
+
this.load();
|
|
3637
|
+
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
3638
|
+
},
|
|
3639
|
+
updateDisabled: function () {
|
|
3640
|
+
this.$el.find('input').prop('disabled', this.isDisabled());
|
|
3641
|
+
},
|
|
3642
|
+
save: function () {
|
|
3643
|
+
var index = this.$el.find('input').index(this.$el.find('input:checked'));
|
|
3644
|
+
this.model.set(this.options.propertyName, this.options.values[index]);
|
|
3645
|
+
},
|
|
3646
|
+
appendOptions: function () {
|
|
3647
|
+
_.each(this.options.values, function (value, index) {
|
|
3648
|
+
var id = this.cid + '_' + value;
|
|
3649
|
+
var wrapper = document.createElement('div');
|
|
3650
|
+
wrapper.className = 'radio_button';
|
|
3651
|
+
var input = document.createElement('input');
|
|
3652
|
+
input.type = 'radio';
|
|
3653
|
+
input.name = this.options.propertyName;
|
|
3654
|
+
input.value = value;
|
|
3655
|
+
input.id = id;
|
|
3656
|
+
var label = document.createElement('label');
|
|
3657
|
+
label.htmlFor = id;
|
|
3658
|
+
var nameSpan = document.createElement('span');
|
|
3659
|
+
nameSpan.className = 'name';
|
|
3660
|
+
nameSpan.textContent = this.options.texts[index];
|
|
3661
|
+
label.appendChild(nameSpan);
|
|
3662
|
+
wrapper.appendChild(input);
|
|
3663
|
+
wrapper.appendChild(document.createTextNode(' '));
|
|
3664
|
+
wrapper.appendChild(label);
|
|
3665
|
+
this.$el.append(wrapper);
|
|
3666
|
+
}, this);
|
|
3667
|
+
},
|
|
3668
|
+
load: function () {
|
|
3669
|
+
if (!this.isClosed) {
|
|
3670
|
+
var value = this.model.get(this.options.propertyName);
|
|
3671
|
+
this.$el.find('input[value="' + value + '"]').prop('checked', true);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
});
|
|
3675
|
+
|
|
2992
3676
|
/**
|
|
2993
3677
|
* Render a separator in a {@link ConfigurationEditorView} tab.
|
|
2994
3678
|
*
|
|
@@ -2998,8 +3682,7 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2998
3682
|
*
|
|
2999
3683
|
* @class
|
|
3000
3684
|
*/
|
|
3001
|
-
|
|
3002
|
-
var SeparatorView = Marionette.View.extend({
|
|
3685
|
+
const SeparatorView = Marionette.View.extend({
|
|
3003
3686
|
className: 'separator'
|
|
3004
3687
|
});
|
|
3005
3688
|
|
|
@@ -3011,12 +3694,14 @@ var SeparatorView = Marionette.View.extend({
|
|
|
3011
3694
|
*
|
|
3012
3695
|
* @class
|
|
3013
3696
|
*/
|
|
3014
|
-
|
|
3015
|
-
var LabelOnlyView = Marionette.ItemView.extend({
|
|
3697
|
+
const LabelOnlyView = Marionette.ItemView.extend({
|
|
3016
3698
|
mixins: [inputView],
|
|
3017
|
-
template:
|
|
3018
|
-
|
|
3019
|
-
|
|
3699
|
+
template: () => `
|
|
3700
|
+
<label>
|
|
3701
|
+
<span class="name"></span>
|
|
3702
|
+
<span class="inline_help"></span>
|
|
3703
|
+
</label>
|
|
3704
|
+
`,
|
|
3020
3705
|
ui: {
|
|
3021
3706
|
label: 'label'
|
|
3022
3707
|
}
|
|
@@ -3037,10 +3722,9 @@ var LabelOnlyView = Marionette.ItemView.extend({
|
|
|
3037
3722
|
*
|
|
3038
3723
|
* @since 12.0
|
|
3039
3724
|
*/
|
|
3040
|
-
|
|
3041
|
-
var EnumTableCellView = TableCellView.extend({
|
|
3725
|
+
const EnumTableCellView = TableCellView.extend({
|
|
3042
3726
|
className: 'enum_table_cell',
|
|
3043
|
-
update: function
|
|
3727
|
+
update: function () {
|
|
3044
3728
|
this.$el.text(this.attributeTranslation('cell_text.' + (this.attributeValue() || 'blank')));
|
|
3045
3729
|
this.$el.attr('title', this.attributeTranslation('cell_title.' + (this.attributeValue() || 'blank'), {
|
|
3046
3730
|
defaultValue: ''
|
|
@@ -3048,7 +3732,7 @@ var EnumTableCellView = TableCellView.extend({
|
|
|
3048
3732
|
}
|
|
3049
3733
|
});
|
|
3050
3734
|
|
|
3051
|
-
function template$
|
|
3735
|
+
function template$f(data) {
|
|
3052
3736
|
var __t, __p = '';
|
|
3053
3737
|
__p += '<a class="remove" title="' +
|
|
3054
3738
|
((__t = ( I18n.t('pageflow.editor.templates.row.destroy') )) == null ? '' : __t) +
|
|
@@ -3078,24 +3762,22 @@ return __p
|
|
|
3078
3762
|
*
|
|
3079
3763
|
* @since 12.0
|
|
3080
3764
|
*/
|
|
3081
|
-
|
|
3082
|
-
var DeleteRowTableCellView = TableCellView.extend({
|
|
3765
|
+
const DeleteRowTableCellView = TableCellView.extend({
|
|
3083
3766
|
className: 'delete_row_table_cell',
|
|
3084
|
-
template: template$
|
|
3767
|
+
template: template$f,
|
|
3085
3768
|
ui: {
|
|
3086
3769
|
removeButton: '.remove'
|
|
3087
3770
|
},
|
|
3088
3771
|
events: {
|
|
3089
3772
|
'click .remove': 'destroy',
|
|
3090
|
-
'click': function
|
|
3773
|
+
'click': function () {
|
|
3091
3774
|
return false;
|
|
3092
3775
|
}
|
|
3093
3776
|
},
|
|
3094
|
-
showButton: function
|
|
3777
|
+
showButton: function () {
|
|
3095
3778
|
if (this.options.toggleDeleteButton) {
|
|
3096
3779
|
var context = this.getModel();
|
|
3097
3780
|
var toggle = context[this.options.toggleDeleteButton].apply(context);
|
|
3098
|
-
|
|
3099
3781
|
if (this.options.invertToggleDeleteButton) {
|
|
3100
3782
|
return !toggle;
|
|
3101
3783
|
} else {
|
|
@@ -3105,11 +3787,11 @@ var DeleteRowTableCellView = TableCellView.extend({
|
|
|
3105
3787
|
return true;
|
|
3106
3788
|
}
|
|
3107
3789
|
},
|
|
3108
|
-
update: function
|
|
3790
|
+
update: function () {
|
|
3109
3791
|
this.ui.removeButton.toggleClass('remove', this.showButton());
|
|
3110
3792
|
this.ui.removeButton.attr('title', this.attributeTranslation('cell_title'));
|
|
3111
3793
|
},
|
|
3112
|
-
destroy: function
|
|
3794
|
+
destroy: function () {
|
|
3113
3795
|
this.getModel().destroy();
|
|
3114
3796
|
}
|
|
3115
3797
|
});
|
|
@@ -3130,10 +3812,9 @@ var DeleteRowTableCellView = TableCellView.extend({
|
|
|
3130
3812
|
*
|
|
3131
3813
|
* @since 12.0
|
|
3132
3814
|
*/
|
|
3133
|
-
|
|
3134
|
-
var PresenceTableCellView = TableCellView.extend({
|
|
3815
|
+
const PresenceTableCellView = TableCellView.extend({
|
|
3135
3816
|
className: 'presence_table_cell',
|
|
3136
|
-
update: function
|
|
3817
|
+
update: function () {
|
|
3137
3818
|
var isPresent = !!this.attributeValue();
|
|
3138
3819
|
this.$el.attr('title', isPresent ? this.attributeTranslation('cell_title.present', {
|
|
3139
3820
|
value: this.attributeValue()
|
|
@@ -3154,18 +3835,18 @@ var PresenceTableCellView = TableCellView.extend({
|
|
|
3154
3835
|
*
|
|
3155
3836
|
* @param {Object} [options]
|
|
3156
3837
|
*
|
|
3157
|
-
* @param {string[]} [options.icons]
|
|
3838
|
+
* @param {string[]|function} [options.icons]
|
|
3158
3839
|
* An array of all possible attribute values to be mapped to HTML
|
|
3159
3840
|
* classes of the same name. A global mapping from those classes to
|
|
3160
3841
|
* icon mixins is provided in
|
|
3161
|
-
* pageflow/ui/table_cells/icon_table_cell.scss.
|
|
3842
|
+
* pageflow/ui/table_cells/icon_table_cell.scss. Pass a function
|
|
3843
|
+
* returning the array to defer reading the values.
|
|
3162
3844
|
*
|
|
3163
3845
|
* @since 12.0
|
|
3164
3846
|
*/
|
|
3165
|
-
|
|
3166
|
-
var IconTableCellView = TableCellView.extend({
|
|
3847
|
+
const IconTableCellView = TableCellView.extend({
|
|
3167
3848
|
className: 'icon_table_cell',
|
|
3168
|
-
update: function
|
|
3849
|
+
update: function () {
|
|
3169
3850
|
var icon = this.attributeValue();
|
|
3170
3851
|
var isPresent = !!this.attributeValue();
|
|
3171
3852
|
this.removeExistingIcons();
|
|
@@ -3174,8 +3855,8 @@ var IconTableCellView = TableCellView.extend({
|
|
|
3174
3855
|
}) : this.attributeTranslation('cell_title.blank'));
|
|
3175
3856
|
this.$el.addClass(icon);
|
|
3176
3857
|
},
|
|
3177
|
-
removeExistingIcons: function
|
|
3178
|
-
this.$el.removeClass(this.options
|
|
3858
|
+
removeExistingIcons: function () {
|
|
3859
|
+
this.$el.removeClass(_.result(this.options, 'icons').join(' '));
|
|
3179
3860
|
}
|
|
3180
3861
|
});
|
|
3181
3862
|
|
|
@@ -3198,65 +3879,59 @@ var IconTableCellView = TableCellView.extend({
|
|
|
3198
3879
|
*
|
|
3199
3880
|
* @since 12.0
|
|
3200
3881
|
*/
|
|
3201
|
-
|
|
3202
|
-
var TextTableCellView = TableCellView.extend({
|
|
3882
|
+
const TextTableCellView = TableCellView.extend({
|
|
3203
3883
|
className: 'text_table_cell',
|
|
3204
|
-
update: function
|
|
3884
|
+
update: function () {
|
|
3205
3885
|
this.$el.text(this._updateText());
|
|
3206
3886
|
},
|
|
3207
|
-
_updateText: function
|
|
3887
|
+
_updateText: function () {
|
|
3208
3888
|
if (this.attributeValue()) {
|
|
3209
3889
|
return this.attributeValue();
|
|
3210
|
-
} else if (typeof this.options.column
|
|
3890
|
+
} else if (typeof this.options.column.default === 'function') {
|
|
3211
3891
|
var options = {};
|
|
3212
|
-
|
|
3213
3892
|
if (this.options.column.contentBinding) {
|
|
3214
3893
|
options = {
|
|
3215
3894
|
contentBinding: this.options.column.contentBinding,
|
|
3216
3895
|
model: this.getModel()
|
|
3217
3896
|
};
|
|
3218
3897
|
}
|
|
3219
|
-
|
|
3220
|
-
return this.options.column["default"](options);
|
|
3898
|
+
return this.options.column.default(options);
|
|
3221
3899
|
} else if ('default' in this.options.column) {
|
|
3222
|
-
return this.options.column
|
|
3900
|
+
return this.options.column.default;
|
|
3223
3901
|
} else {
|
|
3224
3902
|
return I18n$1.t('pageflow.ui.text_table_cell_view.empty');
|
|
3225
3903
|
}
|
|
3226
3904
|
}
|
|
3227
3905
|
});
|
|
3228
3906
|
|
|
3229
|
-
|
|
3230
|
-
subview: function
|
|
3907
|
+
const subviewContainer = {
|
|
3908
|
+
subview: function (view) {
|
|
3231
3909
|
this.subviews = this.subviews || new ChildViewContainer();
|
|
3232
3910
|
this.subviews.add(view.render());
|
|
3233
3911
|
return view;
|
|
3234
3912
|
},
|
|
3235
|
-
appendSubview: function
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3913
|
+
appendSubview: function (view, {
|
|
3914
|
+
to
|
|
3915
|
+
} = {}) {
|
|
3239
3916
|
return (to || this.$el).append(this.subview(view).el);
|
|
3240
3917
|
},
|
|
3241
|
-
onClose: function
|
|
3918
|
+
onClose: function () {
|
|
3242
3919
|
if (this.subviews) {
|
|
3243
3920
|
this.subviews.call('close');
|
|
3244
3921
|
}
|
|
3245
3922
|
}
|
|
3246
3923
|
};
|
|
3247
|
-
|
|
3248
3924
|
if (!Marionette.View.prototype.appendSubview) {
|
|
3249
3925
|
Cocktail.mixin(Marionette.View, subviewContainer);
|
|
3250
3926
|
}
|
|
3251
3927
|
|
|
3252
|
-
|
|
3928
|
+
const tooltipContainer = {
|
|
3253
3929
|
events: {
|
|
3254
|
-
'mouseover [data-tooltip]': function
|
|
3930
|
+
'mouseover [data-tooltip]': function (event) {
|
|
3255
3931
|
if (!this.tooltip.visible) {
|
|
3256
3932
|
var target = $(event.currentTarget);
|
|
3257
3933
|
var key = target.attr('data-tooltip');
|
|
3258
3934
|
var position;
|
|
3259
|
-
|
|
3260
3935
|
if (target.data('tooltipAlign') === 'bottom left') {
|
|
3261
3936
|
position = {
|
|
3262
3937
|
left: target.position().left,
|
|
@@ -3278,19 +3953,18 @@ var tooltipContainer = {
|
|
|
3278
3953
|
top: target.position().top + target.outerHeight() / 2
|
|
3279
3954
|
};
|
|
3280
3955
|
}
|
|
3281
|
-
|
|
3282
3956
|
this.tooltip.show(I18n$1.t(key), position, {
|
|
3283
3957
|
align: target.data('tooltipAlign')
|
|
3284
3958
|
});
|
|
3285
3959
|
}
|
|
3286
3960
|
},
|
|
3287
|
-
'mouseleave [data-tooltip]': function
|
|
3961
|
+
'mouseleave [data-tooltip]': function () {
|
|
3288
3962
|
this.tooltip.hide();
|
|
3289
3963
|
}
|
|
3290
3964
|
},
|
|
3291
|
-
onRender: function
|
|
3965
|
+
onRender: function () {
|
|
3292
3966
|
this.appendSubview(this.tooltip = new TooltipView());
|
|
3293
3967
|
}
|
|
3294
3968
|
};
|
|
3295
3969
|
|
|
3296
|
-
export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, IconTableCellView, JsonInputView, LabelOnlyView, NumberInputView, BaseObject as Object, PresenceTableCellView, ProxyUrlInputView, SelectInputView, SeparatorView, SliderInputView, SortableCollectionView, TableCellView, TableHeaderCellView, TableRowView, TableView, TabsView, TextAreaInputView, TextInputView, TextTableCellView, TooltipView, UrlDisplayView, UrlInputView, attributeBinding, cssModulesUtils, i18nUtils, inputView, inputWithPlaceholderText, serverSideValidation, subviewContainer, tooltipContainer, viewWithValidationErrorMessages };
|
|
3970
|
+
export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ColorPicker, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, FileNameInputView, IconTableCellView, JsonInputView, LabelOnlyView, NumberInputView, BaseObject as Object, PresenceTableCellView, ProxyUrlInputView, RadioButtonGroupInputView, SelectInputView, SeparatorView, SliderInputView, SortableCollectionView, TableCellView, TableHeaderCellView, TableRowView, TableView, TabsView, TextAreaInputView, TextInputView, TextTableCellView, TooltipView, UrlDisplayView, UrlInputView, attributeBinding, attributeBindingUtils, cssModulesUtils, i18nUtils, inputView, inputWithPlaceholderText, serverSideValidation, subviewContainer, tooltipContainer, viewWithValidationErrorMessages };
|