pageflow 17.1.0 → 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 +319 -345
- data/README.md +3 -4
- data/admins/pageflow/accounts.rb +6 -6
- data/admins/pageflow/entry.rb +10 -8
- data/admins/pageflow/membership.rb +11 -11
- data/admins/pageflow/translations.rb +5 -5
- data/app/assets/images/pageflow/admin/icons/comment.svg +1 -0
- data/app/assets/javascripts/pageflow/dist/ui.js +1350 -630
- 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/entry_comments_indicator.scss +45 -0
- data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +8 -1
- 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 +21 -5
- data/app/assets/stylesheets/pageflow/editor/base.scss +9 -1
- data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +13 -1
- 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 +0 -1
- 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 +230 -50
- data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +142 -14
- data/app/assets/stylesheets/pageflow/editor/folder_breadcrumb.scss +40 -0
- data/app/assets/stylesheets/pageflow/editor/info_box.scss +12 -0
- 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 +88 -38
- 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/mixins/pageflow.scss +9 -5
- data/app/assets/stylesheets/pageflow/ui/color_picker.scss +230 -0
- data/app/assets/stylesheets/pageflow/ui/forms.scss +34 -4
- data/app/assets/stylesheets/pageflow/ui/functions.scss +12 -2
- data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +9 -16
- 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 +29 -0
- data/app/assets/stylesheets/pageflow/ui/tabs_view.scss +8 -3
- data/app/assets/stylesheets/pageflow/ui.scss +4 -2
- data/app/controllers/pageflow/editor/entries_controller.rb +1 -0
- data/app/controllers/pageflow/editor/file_folders_controller.rb +80 -0
- data/app/controllers/pageflow/editor/file_import_controller.rb +1 -0
- data/app/controllers/pageflow/editor/files_controller.rb +15 -6
- data/app/controllers/pageflow/editor/oembeds_controller.rb +21 -0
- data/app/controllers/pageflow/entries_controller.rb +17 -13
- 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 +4 -1
- data/app/helpers/pageflow/admin/entries_helper.rb +40 -0
- data/app/helpers/pageflow/admin/widgets_helper.rb +2 -2
- data/app/helpers/pageflow/common_entry_seed_helper.rb +5 -3
- data/app/helpers/pageflow/editor/config_helper.rb +3 -1
- data/app/helpers/pageflow/entries_helper.rb +24 -42
- data/app/helpers/pageflow/entry_json_seed_helper.rb +4 -4
- data/app/helpers/pageflow/public_i18n_helper.rb +9 -8
- data/app/helpers/pageflow/structured_data_helper.rb +4 -1
- data/app/helpers/pageflow/themes_helper.rb +1 -3
- data/app/helpers/pageflow/widgets_helper.rb +2 -1
- data/app/inputs/pageflow_permalink_input.rb +6 -2
- data/app/models/concerns/pageflow/auto_generated_perma_id.rb +11 -4
- data/app/models/concerns/pageflow/reusable_file.rb +1 -1
- data/app/models/concerns/pageflow/serialization_blacklist.rb +2 -4
- data/app/models/concerns/pageflow/translated_attributes.rb +101 -0
- data/app/models/concerns/pageflow/uploadable_file.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 +3 -2
- data/app/models/pageflow/draft_entry.rb +20 -8
- data/app/models/pageflow/entry.rb +2 -0
- data/app/models/pageflow/entry_at_revision.rb +9 -1
- data/app/models/pageflow/entry_comment_summary.rb +114 -0
- data/app/models/pageflow/file_folder.rb +74 -0
- data/app/models/pageflow/file_reuse.rb +3 -2
- data/app/models/pageflow/file_usage.rb +8 -0
- data/app/models/pageflow/image_file.rb +24 -20
- data/app/models/pageflow/image_file_url_templates.rb +3 -3
- data/app/models/pageflow/legal_info.rb +38 -0
- data/app/models/pageflow/nested_revision_component_copy.rb +1 -1
- data/app/models/pageflow/permalink.rb +1 -0
- data/app/models/pageflow/revision.rb +6 -2
- data/app/models/pageflow/site.rb +10 -0
- data/app/models/pageflow/used_file.rb +8 -2
- data/app/models/pageflow/widget.rb +2 -2
- data/app/views/pageflow/audio_files/_audio_file.json.jbuilder +0 -1
- data/app/views/pageflow/editor/config/_seeds.json.jbuilder +4 -2
- data/app/views/pageflow/editor/entries/_entry.json.jbuilder +2 -1
- data/app/views/pageflow/editor/entries/seed.json.erb +1 -0
- 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 +2 -1
- data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +3 -0
- data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +3 -0
- data/app/views/pageflow/files/_file.json.jbuilder +2 -0
- 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/structured_data/_entry.json.jbuilder +2 -3
- data/app/views/pageflow/video_files/_video_file.json.jbuilder +0 -1
- data/config/locales/de.yml +152 -14
- data/config/locales/en.yml +150 -14
- data/config/routes.rb +14 -0
- data/db/migrate/20140418225525_setup_schema.rb +2 -2
- 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 +8665 -3890
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +979 -3571
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +20199 -28120
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +18652 -26584
- data/entry_types/scrolled/app/assets/stylesheets/pageflow_scrolled/ui.scss +2 -0
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +33 -3
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -3
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +21 -1
- 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 +7 -5
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +5 -2
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +13 -5
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +28 -13
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +26 -11
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +2 -2
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/sprockets_helper.rb +16 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +174 -3
- data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +49 -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/storyline.rb +1 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +13 -12
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +30 -10
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +9 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +1 -1
- data/entry_types/scrolled/config/configuration_schemas/pageflow-scrolled.json +414 -0
- data/entry_types/scrolled/config/locales/de.yml +512 -65
- data/entry_types/scrolled/config/locales/en.yml +518 -52
- data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +2 -2
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +51 -6
- data/entry_types/scrolled/lib/pageflow_scrolled/configuration_schemas.rb +91 -0
- 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 +205 -22
- data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +2 -4
- data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +56 -36
- data/entry_types/scrolled/lib/pageflow_scrolled/theme_options_default_scale.rb +35 -0
- data/entry_types/scrolled/lib/pageflow_scrolled.rb +13 -0
- data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +19 -1
- 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 +72 -0
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -1
- data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1181 -915
- 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.js +71 -21
- 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 +1915 -1097
- data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
- data/entry_types/scrolled/package/contentElements-frontend.js +3093 -1679
- data/entry_types/scrolled/package/editor.css +1 -0
- data/entry_types/scrolled/package/editor.js +8667 -4077
- 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-9f76033e.js → PhonePlatformContext-035a99fa.js} +7 -12
- 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-788e9cdb.js → ToggleFullscreenCornerButton-30fd1124.js} +6 -6
- 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-0345ce57.js → Viewer-cc8d4072.js} +84 -92
- 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-eb670c2f.js → index-2e5546f7.js} +36 -44
- 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 +1870 -875
- 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-c2ba875d.js → usePhonePlatform-4ecb96d4.js} +1 -1
- data/entry_types/scrolled/package/frontend/usePhonePlatform-ce9ff08d.js +8 -0
- data/entry_types/scrolled/package/frontend-server.js +20 -209
- data/entry_types/scrolled/package/package.json +5 -3
- 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 +836 -359
- data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
- data/entry_types/scrolled/package/widgets/consentBar.js +269 -290
- data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
- data/entry_types/scrolled/package/widgets/defaultNavigation.js +911 -352
- data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -1
- data/entry_types/scrolled/package/widgets/excursionSheet.js +87 -124
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +62 -29
- data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +32 -13
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -1
- data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +56 -100
- data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
- data/entry_types/scrolled/package/widgets/textInlineFileRights.js +33 -28
- data/entry_types/scrolled/package/widgets-server.js +1 -0
- 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/resque/resque_generator.rb +0 -2
- data/lib/pageflow/configuration.rb +49 -7
- data/lib/pageflow/deprecation.rb +19 -0
- data/lib/pageflow/engine.rb +1 -1
- data/lib/pageflow/entries_controller_env_helper.rb +32 -2
- data/lib/pageflow/entry_export_import/entry_serialization.rb +4 -4
- data/lib/pageflow/entry_export_import/page_type_versions.rb +2 -2
- data/lib/pageflow/entry_export_import/revision_serialization/import.rb +10 -0
- data/lib/pageflow/entry_export_import/revision_serialization.rb +3 -0
- data/lib/pageflow/entry_structured_data_types.rb +43 -0
- data/lib/pageflow/entry_type_configuration.rb +1 -0
- data/lib/pageflow/file_type.rb +2 -2
- data/lib/pageflow/file_types.rb +1 -1
- data/lib/pageflow/oembed_providers.rb +42 -0
- data/lib/pageflow/primary_domain_entry_redirect.rb +6 -0
- data/lib/pageflow/rails_version.rb +13 -2
- data/lib/pageflow/themes.rb +41 -0
- data/lib/pageflow/user_mixin.rb +12 -0
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow.rb +1 -0
- 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 +4378 -1897
- data/package/frontend.js +647 -886
- data/package/package.json +2 -1
- data/package/review.js +384 -0
- data/package/testHelpers.js +248 -188
- data/package/ui.js +1346 -630
- data/package/vendor/stubs/wysihtml5.js +2 -0
- 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/file_folders.rb +8 -0
- data/spec/factories/published_entries.rb +2 -0
- metadata +188 -67
- data/app/assets/stylesheets/pageflow/editor/select_button.scss +0 -51
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/generated_media_queries_helper.rb +0 -55
- data/entry_types/scrolled/package/frontend/FloatingPortalRootProvider-51914be7.js +0 -5439
- data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +0 -1932
- data/entry_types/scrolled/package/frontend/Viewer-cdc549cc.js +0 -147
- data/entry_types/scrolled/package/frontend/Wavesurfer-1cdc3925.js +0 -313
- data/entry_types/scrolled/package/frontend/components-96660ffd.js +0 -3803
- data/entry_types/scrolled/package/frontend/inherits-539844a6.js +0 -99
- data/entry_types/scrolled/package/frontend/useContentElementEditorState-77fe6c79.js +0 -51
- data/entry_types/scrolled/package/widgets/excursionDialog.css +0 -1
- data/entry_types/scrolled/package/widgets/excursionDialog.js +0 -109
- 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
|
@@ -6,7 +6,6 @@ import Backbone from 'backbone';
|
|
|
6
6
|
import Sortable from 'sortablejs';
|
|
7
7
|
import ChildViewContainer from 'backbone.babysitter';
|
|
8
8
|
import IScroll from 'iscroll';
|
|
9
|
-
import 'jquery.minicolors';
|
|
10
9
|
import wysihtml5 from 'wysihtml5';
|
|
11
10
|
import 'jquery-ui';
|
|
12
11
|
import Cocktail from 'cocktail';
|
|
@@ -142,64 +141,6 @@ var i18nUtils = /*#__PURE__*/Object.freeze({
|
|
|
142
141
|
translationKeysWithSuffix: translationKeysWithSuffix
|
|
143
142
|
});
|
|
144
143
|
|
|
145
|
-
function _arrayWithHoles(arr) {
|
|
146
|
-
if (Array.isArray(arr)) return arr;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function _iterableToArrayLimit(arr, i) {
|
|
150
|
-
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
|
|
151
|
-
var _arr = [];
|
|
152
|
-
var _n = true;
|
|
153
|
-
var _d = false;
|
|
154
|
-
var _e = undefined;
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
|
158
|
-
_arr.push(_s.value);
|
|
159
|
-
|
|
160
|
-
if (i && _arr.length === i) break;
|
|
161
|
-
}
|
|
162
|
-
} catch (err) {
|
|
163
|
-
_d = true;
|
|
164
|
-
_e = err;
|
|
165
|
-
} finally {
|
|
166
|
-
try {
|
|
167
|
-
if (!_n && _i["return"] != null) _i["return"]();
|
|
168
|
-
} finally {
|
|
169
|
-
if (_d) throw _e;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return _arr;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function _arrayLikeToArray(arr, len) {
|
|
177
|
-
if (len == null || len > arr.length) len = arr.length;
|
|
178
|
-
|
|
179
|
-
for (var i = 0, arr2 = new Array(len); i < len; i++) {
|
|
180
|
-
arr2[i] = arr[i];
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return arr2;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
function _unsupportedIterableToArray(o, minLen) {
|
|
187
|
-
if (!o) return;
|
|
188
|
-
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
189
|
-
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
190
|
-
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
191
|
-
if (n === "Map" || n === "Set") return Array.from(n);
|
|
192
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function _nonIterableRest() {
|
|
196
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function _slicedToArray(arr, i) {
|
|
200
|
-
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
144
|
/**
|
|
204
145
|
* Create object that can be passed to Marionette ui property from CSS
|
|
205
146
|
* module object.
|
|
@@ -239,11 +180,8 @@ function _slicedToArray(arr, i) {
|
|
|
239
180
|
*
|
|
240
181
|
* @memberof cssModulesUtils
|
|
241
182
|
*/
|
|
242
|
-
function ui(styles) {
|
|
243
|
-
|
|
244
|
-
classNames[_key - 1] = arguments[_key];
|
|
245
|
-
}
|
|
246
|
-
return classNames.reduce(function (result, className) {
|
|
183
|
+
function ui(styles, ...classNames) {
|
|
184
|
+
return classNames.reduce((result, className) => {
|
|
247
185
|
result[className] = selector(styles, className);
|
|
248
186
|
return result;
|
|
249
187
|
}, {});
|
|
@@ -287,12 +225,9 @@ function ui(styles) {
|
|
|
287
225
|
* @memberof cssModulesUtils
|
|
288
226
|
*/
|
|
289
227
|
function events(styles, mapping) {
|
|
290
|
-
return Object.keys(mapping).reduce(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
event = _key$split2[0],
|
|
294
|
-
className = _key$split2[1];
|
|
295
|
-
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];
|
|
296
231
|
return result;
|
|
297
232
|
}, {});
|
|
298
233
|
}
|
|
@@ -310,11 +245,11 @@ function events(styles, mapping) {
|
|
|
310
245
|
* @memberof cssModulesUtils
|
|
311
246
|
*/
|
|
312
247
|
function selector(styles, className) {
|
|
313
|
-
|
|
248
|
+
const classNames = styles[className];
|
|
314
249
|
if (!classNames) {
|
|
315
|
-
throw new Error(
|
|
250
|
+
throw new Error(`Unknown class name ${className} in mapping. Knwon names: ${Object.keys(styles).join(', ')}.`);
|
|
316
251
|
}
|
|
317
|
-
return
|
|
252
|
+
return `.${classNames.replace(/ /g, '.')}`;
|
|
318
253
|
}
|
|
319
254
|
|
|
320
255
|
var cssModulesUtils = /*#__PURE__*/Object.freeze({
|
|
@@ -324,6 +259,56 @@ var cssModulesUtils = /*#__PURE__*/Object.freeze({
|
|
|
324
259
|
selector: selector
|
|
325
260
|
});
|
|
326
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
|
+
|
|
327
312
|
// Class-y constructor by github.com/opensas
|
|
328
313
|
// https://github.com/jashkenas/backbone/issues/2601
|
|
329
314
|
|
|
@@ -331,30 +316,29 @@ function BaseObject(options) {
|
|
|
331
316
|
this.initialize.apply(this, arguments);
|
|
332
317
|
}
|
|
333
318
|
_.extend(BaseObject.prototype, Backbone.Events, {
|
|
334
|
-
initialize: function
|
|
319
|
+
initialize: function (options) {}
|
|
335
320
|
});
|
|
336
321
|
|
|
337
322
|
// The self-propagating extend function that Backbone classes use.
|
|
338
323
|
BaseObject.extend = Backbone.Model.extend;
|
|
339
324
|
|
|
340
|
-
|
|
341
|
-
initialize
|
|
342
|
-
var _this = this;
|
|
325
|
+
const serverSideValidation = {
|
|
326
|
+
initialize() {
|
|
343
327
|
this.validationErrors = {};
|
|
344
|
-
this.listenTo(this, 'error',
|
|
328
|
+
this.listenTo(this, 'error', (model, request) => {
|
|
345
329
|
if (request.status === 422) {
|
|
346
|
-
|
|
347
|
-
|
|
330
|
+
this.validationErrors = JSON.parse(request.responseText).errors;
|
|
331
|
+
this.trigger('invalid');
|
|
348
332
|
}
|
|
349
333
|
});
|
|
350
|
-
this.listenTo(this, 'sync',
|
|
351
|
-
|
|
334
|
+
this.listenTo(this, 'sync', () => {
|
|
335
|
+
this.validationErrors = {};
|
|
352
336
|
});
|
|
353
337
|
}
|
|
354
338
|
};
|
|
355
339
|
|
|
356
|
-
|
|
357
|
-
initialize: function
|
|
340
|
+
const CollectionView = Marionette.View.extend({
|
|
341
|
+
initialize: function () {
|
|
358
342
|
this.rendered = false;
|
|
359
343
|
this.itemViews = new ChildViewContainer();
|
|
360
344
|
this.collection.map(this.addItem, this);
|
|
@@ -372,7 +356,7 @@ var CollectionView = Marionette.View.extend({
|
|
|
372
356
|
});
|
|
373
357
|
}
|
|
374
358
|
},
|
|
375
|
-
render: function
|
|
359
|
+
render: function () {
|
|
376
360
|
if (!this.rendered) {
|
|
377
361
|
this.$el.append(this.itemViews.map(function (itemView) {
|
|
378
362
|
itemView.$el.data('view', itemView);
|
|
@@ -383,11 +367,11 @@ var CollectionView = Marionette.View.extend({
|
|
|
383
367
|
}
|
|
384
368
|
return this;
|
|
385
369
|
},
|
|
386
|
-
onClose: function
|
|
370
|
+
onClose: function () {
|
|
387
371
|
this.itemViews.call('close');
|
|
388
372
|
this.closePlaceHolderView();
|
|
389
373
|
},
|
|
390
|
-
addItem: function
|
|
374
|
+
addItem: function (item) {
|
|
391
375
|
var view = new this.options.itemViewConstructor(_.extend({
|
|
392
376
|
model: item
|
|
393
377
|
}, this.getItemViewOptions(item)));
|
|
@@ -404,7 +388,7 @@ var CollectionView = Marionette.View.extend({
|
|
|
404
388
|
this.togglePlaceHolder();
|
|
405
389
|
}
|
|
406
390
|
},
|
|
407
|
-
removeItem: function
|
|
391
|
+
removeItem: function (item) {
|
|
408
392
|
var view = this.itemViews.findByModel(item);
|
|
409
393
|
if (view) {
|
|
410
394
|
this.itemViews.remove(view);
|
|
@@ -412,7 +396,7 @@ var CollectionView = Marionette.View.extend({
|
|
|
412
396
|
this.togglePlaceHolder();
|
|
413
397
|
}
|
|
414
398
|
},
|
|
415
|
-
sort: function
|
|
399
|
+
sort: function () {
|
|
416
400
|
var last = null;
|
|
417
401
|
this.collection.each(function (item) {
|
|
418
402
|
var itemView = this.itemViews.findByModel(item);
|
|
@@ -429,31 +413,36 @@ var CollectionView = Marionette.View.extend({
|
|
|
429
413
|
last = element;
|
|
430
414
|
}, this);
|
|
431
415
|
},
|
|
432
|
-
getItemViewOptions: function
|
|
416
|
+
getItemViewOptions: function (item) {
|
|
433
417
|
if (typeof this.options.itemViewOptions === 'function') {
|
|
434
418
|
return this.options.itemViewOptions(item);
|
|
435
419
|
} else {
|
|
436
420
|
return this.options.itemViewOptions || {};
|
|
437
421
|
}
|
|
438
422
|
},
|
|
439
|
-
closePlaceHolderView: function
|
|
423
|
+
closePlaceHolderView: function () {
|
|
440
424
|
if (this.placeHolderView) {
|
|
441
425
|
this.placeHolderView.close();
|
|
442
426
|
this.placeHolderView = null;
|
|
443
427
|
}
|
|
444
428
|
},
|
|
445
|
-
togglePlaceHolder: function
|
|
429
|
+
togglePlaceHolder: function () {
|
|
446
430
|
var lastPlaceholderConstructor = this.placeHolderConstructor;
|
|
447
431
|
this.placeHolderConstructor = this.getPlaceHolderConstructor();
|
|
448
432
|
if (this.itemViews.length || !this.placeHolderConstructor) {
|
|
449
433
|
this.closePlaceHolderView();
|
|
450
434
|
} else if (!this.placeHolderView || lastPlaceholderConstructor !== this.placeHolderConstructor) {
|
|
451
435
|
this.closePlaceHolderView();
|
|
452
|
-
this.placeHolderView = new this.placeHolderConstructor();
|
|
436
|
+
this.placeHolderView = new this.placeHolderConstructor(this.getPlaceHolderViewOptions());
|
|
453
437
|
this.$el.append(this.placeHolderView.render().el);
|
|
454
438
|
}
|
|
455
439
|
},
|
|
456
|
-
|
|
440
|
+
getPlaceHolderViewOptions: function () {
|
|
441
|
+
if (this.placeHolderConstructor === this.options.blankSlateViewConstructor) {
|
|
442
|
+
return this.options.blankSlateViewOptions;
|
|
443
|
+
}
|
|
444
|
+
},
|
|
445
|
+
getPlaceHolderConstructor: function () {
|
|
457
446
|
if (this.loading && this.options.loadingViewConstructor) {
|
|
458
447
|
return this.options.loadingViewConstructor;
|
|
459
448
|
} else if (this.options.blankSlateViewConstructor) {
|
|
@@ -462,9 +451,8 @@ var CollectionView = Marionette.View.extend({
|
|
|
462
451
|
}
|
|
463
452
|
});
|
|
464
453
|
|
|
465
|
-
|
|
466
|
-
render: function
|
|
467
|
-
var _this = this;
|
|
454
|
+
const SortableCollectionView = CollectionView.extend({
|
|
455
|
+
render: function () {
|
|
468
456
|
CollectionView.prototype.render.call(this);
|
|
469
457
|
this.sortable = Sortable.create(this.el, {
|
|
470
458
|
group: this.options.connectWith,
|
|
@@ -472,125 +460,90 @@ var SortableCollectionView = CollectionView.extend({
|
|
|
472
460
|
ghostClass: 'sortable-placeholder',
|
|
473
461
|
forceFallback: this.options.forceDraggableFallback,
|
|
474
462
|
fallbackTolerance: 3,
|
|
475
|
-
onEnd:
|
|
476
|
-
|
|
477
|
-
if (item.parent().is(
|
|
478
|
-
|
|
463
|
+
onEnd: event => {
|
|
464
|
+
const item = $(event.item);
|
|
465
|
+
if (item.parent().is(this.el)) {
|
|
466
|
+
this.updateOrder();
|
|
479
467
|
}
|
|
480
468
|
},
|
|
481
|
-
onRemove:
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
469
|
+
onRemove: event => {
|
|
470
|
+
const view = $(event.item).data('view');
|
|
471
|
+
this.itemViews.remove(view);
|
|
472
|
+
this.collection.remove(view.model);
|
|
485
473
|
},
|
|
486
|
-
onSort:
|
|
487
|
-
if (event.from !== event.to && event.to ===
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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();
|
|
493
481
|
}
|
|
494
482
|
}
|
|
495
483
|
});
|
|
496
484
|
return this;
|
|
497
485
|
},
|
|
498
|
-
onClose
|
|
486
|
+
onClose() {
|
|
499
487
|
CollectionView.prototype.onClose.call(this);
|
|
500
488
|
this.sortable.destroy();
|
|
501
489
|
},
|
|
502
|
-
disableSorting
|
|
490
|
+
disableSorting() {
|
|
503
491
|
this.sortable.option('disabled', true);
|
|
504
492
|
},
|
|
505
|
-
enableSorting
|
|
493
|
+
enableSorting() {
|
|
506
494
|
this.sortable.option('disabled', false);
|
|
507
495
|
},
|
|
508
|
-
addItem: function
|
|
496
|
+
addItem: function (item) {
|
|
509
497
|
if (!this.itemViews.findByModel(item)) {
|
|
510
498
|
CollectionView.prototype.addItem.call(this, item);
|
|
511
499
|
}
|
|
512
500
|
},
|
|
513
|
-
removeItem: function
|
|
501
|
+
removeItem: function (item) {
|
|
514
502
|
if (this.itemViews.findByModel(item)) {
|
|
515
503
|
CollectionView.prototype.removeItem.call(this, item);
|
|
516
504
|
}
|
|
517
505
|
},
|
|
518
|
-
updateOrder: function
|
|
506
|
+
updateOrder: function () {
|
|
519
507
|
this.reindexPositions();
|
|
520
508
|
this.collection.sort();
|
|
521
509
|
this.collection.saveOrder();
|
|
522
510
|
},
|
|
523
|
-
reindexPositions: function
|
|
511
|
+
reindexPositions: function () {
|
|
524
512
|
this.$el.children().each(function (index) {
|
|
525
513
|
$(this).data('view').model.set('position', index);
|
|
526
514
|
});
|
|
527
515
|
}
|
|
528
516
|
});
|
|
529
517
|
|
|
530
|
-
|
|
531
|
-
if (source == null) return {};
|
|
532
|
-
var target = {};
|
|
533
|
-
var sourceKeys = Object.keys(source);
|
|
534
|
-
var key, i;
|
|
535
|
-
|
|
536
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
537
|
-
key = sourceKeys[i];
|
|
538
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
539
|
-
target[key] = source[key];
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
return target;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
function _objectWithoutProperties(source, excluded) {
|
|
546
|
-
if (source == null) return {};
|
|
547
|
-
var target = _objectWithoutPropertiesLoose(source, excluded);
|
|
548
|
-
var key, i;
|
|
549
|
-
|
|
550
|
-
if (Object.getOwnPropertySymbols) {
|
|
551
|
-
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
|
552
|
-
|
|
553
|
-
for (i = 0; i < sourceSymbolKeys.length; i++) {
|
|
554
|
-
key = sourceSymbolKeys[i];
|
|
555
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
556
|
-
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
|
557
|
-
target[key] = source[key];
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
return target;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
var _excluded = ["ignoreUndefined"];
|
|
565
|
-
var ConfigurationEditorTabView = Marionette.View.extend({
|
|
518
|
+
const ConfigurationEditorTabView = Marionette.View.extend({
|
|
566
519
|
className: 'configuration_editor_tab',
|
|
567
|
-
initialize: function
|
|
520
|
+
initialize: function () {
|
|
568
521
|
this.inputs = new ChildViewContainer();
|
|
569
522
|
this.groups = this.options.groups || ConfigurationEditorTabView.groups;
|
|
570
523
|
},
|
|
571
|
-
input: function
|
|
524
|
+
input: function (propertyName, view, options) {
|
|
572
525
|
this.view(view, _.extend({
|
|
573
526
|
placeholderModel: this.options.placeholderModel,
|
|
574
527
|
propertyName: propertyName,
|
|
575
528
|
attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
|
|
576
529
|
}, options || {}));
|
|
577
530
|
},
|
|
578
|
-
view: function view
|
|
579
|
-
this.inputs.add(new
|
|
531
|
+
view: function (view, options) {
|
|
532
|
+
this.inputs.add(new view(_.extend({
|
|
580
533
|
model: this.model,
|
|
581
534
|
parentTab: this.options.tab
|
|
582
535
|
}, options || {})));
|
|
583
536
|
},
|
|
584
|
-
group: function
|
|
537
|
+
group: function (name, options) {
|
|
585
538
|
this.groups.apply(name, this, options);
|
|
586
539
|
},
|
|
587
|
-
render: function
|
|
540
|
+
render: function () {
|
|
588
541
|
this.inputs.each(function (input) {
|
|
589
542
|
this.$el.append(input.render().el);
|
|
590
543
|
}, this);
|
|
591
544
|
return this;
|
|
592
545
|
},
|
|
593
|
-
onClose: function
|
|
546
|
+
onClose: function () {
|
|
594
547
|
if (this.inputs) {
|
|
595
548
|
this.inputs.call('close');
|
|
596
549
|
}
|
|
@@ -604,10 +557,10 @@ ConfigurationEditorTabView.Groups = function () {
|
|
|
604
557
|
}
|
|
605
558
|
groups[name] = fn;
|
|
606
559
|
};
|
|
607
|
-
this.apply = function (name, context
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
560
|
+
this.apply = function (name, context, {
|
|
561
|
+
ignoreUndefined,
|
|
562
|
+
...options
|
|
563
|
+
} = {}) {
|
|
611
564
|
if (!(name in groups)) {
|
|
612
565
|
if (ignoreUndefined) {
|
|
613
566
|
return;
|
|
@@ -621,7 +574,7 @@ ConfigurationEditorTabView.groups = new ConfigurationEditorTabView.Groups();
|
|
|
621
574
|
|
|
622
575
|
function template(data) {
|
|
623
576
|
var __p = '';
|
|
624
|
-
__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';
|
|
625
578
|
return __p
|
|
626
579
|
}
|
|
627
580
|
|
|
@@ -647,36 +600,43 @@ return __p
|
|
|
647
600
|
*
|
|
648
601
|
* @class
|
|
649
602
|
*/
|
|
650
|
-
|
|
651
|
-
template
|
|
603
|
+
const TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
604
|
+
template,
|
|
652
605
|
className: 'tabs_view',
|
|
653
606
|
ui: {
|
|
654
|
-
|
|
655
|
-
scroller: '.tabs_view-scroller'
|
|
607
|
+
tabs: '.tabs_view-tabs',
|
|
608
|
+
scroller: '.tabs_view-scroller',
|
|
609
|
+
container: '.tabs_view-container'
|
|
656
610
|
},
|
|
657
611
|
regions: {
|
|
658
612
|
container: '.tabs_view-container'
|
|
659
613
|
},
|
|
660
614
|
events: {
|
|
661
|
-
'click .tabs_view-
|
|
662
|
-
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);
|
|
663
620
|
}
|
|
664
621
|
},
|
|
665
|
-
initialize: function
|
|
622
|
+
initialize: function () {
|
|
666
623
|
this.tabFactoryFns = {};
|
|
667
624
|
this.tabNames = [];
|
|
668
625
|
this.currentTabName = null;
|
|
669
626
|
this._refreshScrollerOnSideBarResize();
|
|
670
627
|
},
|
|
671
|
-
tab: function
|
|
628
|
+
tab: function (name, factoryFn) {
|
|
672
629
|
this.tabFactoryFns[name] = factoryFn;
|
|
673
630
|
this.tabNames.push(name);
|
|
674
631
|
},
|
|
675
|
-
onRender: function
|
|
632
|
+
onRender: function () {
|
|
676
633
|
_.each(this.tabNames, function (name) {
|
|
677
634
|
var label = findTranslation(this._labelTranslationKeys(name));
|
|
678
|
-
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);
|
|
679
638
|
}, this);
|
|
639
|
+
this.ui.container.attr('id', this._panelId()).attr('role', 'tabpanel');
|
|
680
640
|
this.scroller = new IScroll(this.ui.scroller[0], {
|
|
681
641
|
scrollX: true,
|
|
682
642
|
scrollY: false,
|
|
@@ -684,14 +644,22 @@ var TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
|
684
644
|
mouseWheel: true,
|
|
685
645
|
preventDefault: false
|
|
686
646
|
});
|
|
687
|
-
this.changeTab(this.defaultTab()
|
|
647
|
+
this.changeTab(this.defaultTab(), {
|
|
648
|
+
refresh: true
|
|
649
|
+
});
|
|
688
650
|
},
|
|
689
|
-
changeTab: function
|
|
690
|
-
|
|
691
|
-
|
|
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
|
+
}
|
|
692
658
|
this.currentTabName = name;
|
|
659
|
+
this._updateActiveTab(name, options.focusTab);
|
|
660
|
+
this._updateActivePanel(name);
|
|
693
661
|
},
|
|
694
|
-
defaultTab: function
|
|
662
|
+
defaultTab: function () {
|
|
695
663
|
if (_.include(this.tabNames, this.options.defaultTab)) {
|
|
696
664
|
return this.options.defaultTab;
|
|
697
665
|
} else {
|
|
@@ -701,19 +669,23 @@ var TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
|
701
669
|
/**
|
|
702
670
|
* Rerender current tab.
|
|
703
671
|
*/
|
|
704
|
-
refresh: function
|
|
705
|
-
|
|
672
|
+
refresh: function () {
|
|
673
|
+
if (this.currentTabName) {
|
|
674
|
+
this.changeTab(this.currentTabName, {
|
|
675
|
+
refresh: true
|
|
676
|
+
});
|
|
677
|
+
}
|
|
706
678
|
},
|
|
707
679
|
/**
|
|
708
680
|
* Adjust tabs scroller to changed width of view.
|
|
709
681
|
*/
|
|
710
|
-
refreshScroller: function
|
|
682
|
+
refreshScroller: function () {
|
|
711
683
|
this.scroller.refresh();
|
|
712
684
|
},
|
|
713
|
-
toggleSpinnerOnTab: function
|
|
685
|
+
toggleSpinnerOnTab: function (name, visible) {
|
|
714
686
|
this.$('[data-tab-name=' + name + ']').toggleClass('spinner', visible);
|
|
715
687
|
},
|
|
716
|
-
_labelTranslationKeys: function
|
|
688
|
+
_labelTranslationKeys: function (name) {
|
|
717
689
|
var result = _.map(this.options.translationKeyPrefixes, function (prefix) {
|
|
718
690
|
return prefix + '.' + name;
|
|
719
691
|
});
|
|
@@ -725,23 +697,85 @@ var TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
|
725
697
|
}
|
|
726
698
|
return result;
|
|
727
699
|
},
|
|
728
|
-
|
|
700
|
+
_updateActiveTab: function (activeTabName, focusTab) {
|
|
729
701
|
var scroller = this.scroller;
|
|
730
|
-
this.
|
|
731
|
-
|
|
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) {
|
|
732
707
|
scroller.scrollToElement(this, 200, true);
|
|
733
|
-
|
|
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
|
+
}
|
|
734
715
|
} else {
|
|
735
|
-
|
|
716
|
+
button.removeClass('active');
|
|
717
|
+
button.attr('aria-selected', 'false');
|
|
718
|
+
button.attr('tabindex', '-1');
|
|
736
719
|
}
|
|
737
720
|
});
|
|
738
721
|
},
|
|
739
|
-
|
|
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 () {
|
|
740
768
|
if (pageflow.app) {
|
|
741
769
|
this.listenTo(pageflow.app, 'resize', function () {
|
|
742
770
|
this.scroller.refresh();
|
|
743
771
|
});
|
|
744
772
|
}
|
|
773
|
+
},
|
|
774
|
+
_tabId: function (name) {
|
|
775
|
+
return this.cid + '-tab-' + name;
|
|
776
|
+
},
|
|
777
|
+
_panelId: function () {
|
|
778
|
+
return this.cid + '-panel';
|
|
745
779
|
}
|
|
746
780
|
});
|
|
747
781
|
|
|
@@ -770,9 +804,9 @@ var TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
|
|
|
770
804
|
*
|
|
771
805
|
* @class
|
|
772
806
|
*/
|
|
773
|
-
|
|
807
|
+
const ConfigurationEditorView = Marionette.View.extend({
|
|
774
808
|
className: 'configuration_editor',
|
|
775
|
-
initialize: function
|
|
809
|
+
initialize: function () {
|
|
776
810
|
this.tabsView = new TabsView({
|
|
777
811
|
translationKeyPrefixes: this.options.tabTranslationKeyPrefixes || [this.options.tabTranslationKeyPrefix],
|
|
778
812
|
fallbackTranslationKeyPrefix: 'pageflow.ui.configuration_editor.tabs',
|
|
@@ -780,10 +814,10 @@ var ConfigurationEditorView = Marionette.View.extend({
|
|
|
780
814
|
});
|
|
781
815
|
this.configure();
|
|
782
816
|
},
|
|
783
|
-
configure: function
|
|
784
|
-
tab: function
|
|
817
|
+
configure: function () {},
|
|
818
|
+
tab: function (name, callbackOrOptions, callback) {
|
|
785
819
|
callback = callback || callbackOrOptions;
|
|
786
|
-
|
|
820
|
+
const options = callback ? callbackOrOptions : {};
|
|
787
821
|
this.tabsView.tab(name, _.bind(function () {
|
|
788
822
|
var tabView = new ConfigurationEditorTabView({
|
|
789
823
|
model: options.model || this.model,
|
|
@@ -798,23 +832,23 @@ var ConfigurationEditorView = Marionette.View.extend({
|
|
|
798
832
|
/**
|
|
799
833
|
* Rerender current tab.
|
|
800
834
|
*/
|
|
801
|
-
refresh: function
|
|
835
|
+
refresh: function () {
|
|
802
836
|
this.tabsView.refresh();
|
|
803
837
|
},
|
|
804
838
|
/**
|
|
805
839
|
* Adjust tabs scroller to changed width of view.
|
|
806
840
|
*/
|
|
807
|
-
refreshScroller: function
|
|
841
|
+
refreshScroller: function () {
|
|
808
842
|
this.tabsView.refreshScroller();
|
|
809
843
|
},
|
|
810
|
-
render: function
|
|
844
|
+
render: function () {
|
|
811
845
|
this.$el.append(this.subview(this.tabsView).el);
|
|
812
846
|
return this;
|
|
813
847
|
}
|
|
814
848
|
});
|
|
815
849
|
_.extend(ConfigurationEditorView, {
|
|
816
850
|
repository: {},
|
|
817
|
-
register: function
|
|
851
|
+
register: function (pageTypeName, prototype) {
|
|
818
852
|
this.repository[pageTypeName] = ConfigurationEditorView.extend(prototype);
|
|
819
853
|
}
|
|
820
854
|
});
|
|
@@ -839,13 +873,13 @@ return __p
|
|
|
839
873
|
*
|
|
840
874
|
* @since 12.0
|
|
841
875
|
*/
|
|
842
|
-
|
|
876
|
+
const TableCellView = Marionette.ItemView.extend({
|
|
843
877
|
tagName: 'td',
|
|
844
878
|
template: template$1,
|
|
845
|
-
className: function
|
|
879
|
+
className: function () {
|
|
846
880
|
return this.options.className;
|
|
847
881
|
},
|
|
848
|
-
onRender: function
|
|
882
|
+
onRender: function () {
|
|
849
883
|
this.listenTo(this.getModel(), 'change:' + this.options.column.name, this.update);
|
|
850
884
|
this.setupContentBinding();
|
|
851
885
|
this.update();
|
|
@@ -853,20 +887,20 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
853
887
|
/**
|
|
854
888
|
* Override in concrete cell view.
|
|
855
889
|
*/
|
|
856
|
-
update: function
|
|
890
|
+
update: function () {
|
|
857
891
|
throw 'Not implemented';
|
|
858
892
|
},
|
|
859
893
|
/**
|
|
860
894
|
* Returns the column attribute's value in the row model.
|
|
861
895
|
*/
|
|
862
|
-
attributeValue: function
|
|
896
|
+
attributeValue: function () {
|
|
863
897
|
if (typeof this.options.column.value == 'function') {
|
|
864
898
|
return this.options.column.value(this.model);
|
|
865
899
|
} else {
|
|
866
900
|
return this.getModel().get(this.options.column.name);
|
|
867
901
|
}
|
|
868
902
|
},
|
|
869
|
-
getModel: function
|
|
903
|
+
getModel: function () {
|
|
870
904
|
if (this.options.column.configurationAttribute) {
|
|
871
905
|
return this.model.configuration;
|
|
872
906
|
} else {
|
|
@@ -891,10 +925,10 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
891
925
|
* // Looks for keys of the form:
|
|
892
926
|
* // <table_view_translation_key_prefix>.<column_attribute>.cell_title
|
|
893
927
|
*/
|
|
894
|
-
attributeTranslation: function
|
|
928
|
+
attributeTranslation: function (keyName, options) {
|
|
895
929
|
return findTranslation(this.attributeTranslationKeys(keyName), options);
|
|
896
930
|
},
|
|
897
|
-
attributeTranslationKeys: function
|
|
931
|
+
attributeTranslationKeys: function (keyName) {
|
|
898
932
|
return _(this.options.attributeTranslationKeyPrefixes || []).map(function (prefix) {
|
|
899
933
|
return prefix + '.' + this.options.column.name + '.' + keyName;
|
|
900
934
|
}, this);
|
|
@@ -908,7 +942,7 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
908
942
|
*
|
|
909
943
|
* @protected
|
|
910
944
|
*/
|
|
911
|
-
setupContentBinding: function
|
|
945
|
+
setupContentBinding: function () {
|
|
912
946
|
if (this.options.column.contentBinding) {
|
|
913
947
|
this.listenTo(this.getModel(), 'change:' + this.options.column.contentBinding, this.update);
|
|
914
948
|
this.update();
|
|
@@ -916,30 +950,30 @@ var TableCellView = Marionette.ItemView.extend({
|
|
|
916
950
|
}
|
|
917
951
|
});
|
|
918
952
|
|
|
919
|
-
|
|
953
|
+
const TableHeaderCellView = TableCellView.extend({
|
|
920
954
|
tagName: 'th',
|
|
921
|
-
render: function
|
|
955
|
+
render: function () {
|
|
922
956
|
this.$el.text(this.options.column.headerText || this.attributeTranslation('column_header'));
|
|
923
957
|
this.$el.data('columnName', this.options.column.name);
|
|
924
958
|
return this;
|
|
925
959
|
}
|
|
926
960
|
});
|
|
927
961
|
|
|
928
|
-
|
|
962
|
+
const TableRowView = Marionette.View.extend({
|
|
929
963
|
tagName: 'tr',
|
|
930
964
|
events: {
|
|
931
|
-
'click': function
|
|
965
|
+
'click': function () {
|
|
932
966
|
if (this.options.selection) {
|
|
933
967
|
this.options.selection.set(this.selectionAttribute(), this.model);
|
|
934
968
|
}
|
|
935
969
|
}
|
|
936
970
|
},
|
|
937
|
-
initialize: function
|
|
971
|
+
initialize: function () {
|
|
938
972
|
if (this.options.selection) {
|
|
939
973
|
this.listenTo(this.options.selection, 'change', this.updateClassName);
|
|
940
974
|
}
|
|
941
975
|
},
|
|
942
|
-
render: function
|
|
976
|
+
render: function () {
|
|
943
977
|
_(this.options.columns).each(function (column) {
|
|
944
978
|
this.appendSubview(new column.cellView(_.extend({
|
|
945
979
|
model: this.model,
|
|
@@ -950,13 +984,13 @@ var TableRowView = Marionette.View.extend({
|
|
|
950
984
|
this.updateClassName();
|
|
951
985
|
return this;
|
|
952
986
|
},
|
|
953
|
-
updateClassName: function
|
|
987
|
+
updateClassName: function () {
|
|
954
988
|
this.$el.toggleClass('is_selected', this.isSelected());
|
|
955
989
|
},
|
|
956
|
-
isSelected: function
|
|
990
|
+
isSelected: function () {
|
|
957
991
|
return this.options.selection && this.options.selection.get(this.selectionAttribute()) === this.model;
|
|
958
992
|
},
|
|
959
|
-
selectionAttribute: function
|
|
993
|
+
selectionAttribute: function () {
|
|
960
994
|
return this.options.selectionAttribute || 'current';
|
|
961
995
|
}
|
|
962
996
|
});
|
|
@@ -977,7 +1011,7 @@ __p += '<td colspan="' +
|
|
|
977
1011
|
return __p
|
|
978
1012
|
}
|
|
979
1013
|
|
|
980
|
-
|
|
1014
|
+
const TableView = Marionette.ItemView.extend({
|
|
981
1015
|
tagName: 'table',
|
|
982
1016
|
className: 'table_view',
|
|
983
1017
|
template: template$2,
|
|
@@ -985,7 +1019,7 @@ var TableView = Marionette.ItemView.extend({
|
|
|
985
1019
|
headRow: 'thead tr',
|
|
986
1020
|
body: 'tbody'
|
|
987
1021
|
},
|
|
988
|
-
onRender: function
|
|
1022
|
+
onRender: function () {
|
|
989
1023
|
var view = this;
|
|
990
1024
|
_(this.options.columns).each(function (column) {
|
|
991
1025
|
this.ui.headRow.append(this.subview(new TableHeaderCellView({
|
|
@@ -1007,7 +1041,7 @@ var TableView = Marionette.ItemView.extend({
|
|
|
1007
1041
|
tagName: 'tr',
|
|
1008
1042
|
className: 'blank_slate',
|
|
1009
1043
|
template: blankSlateTemplate,
|
|
1010
|
-
serializeData: function
|
|
1044
|
+
serializeData: function () {
|
|
1011
1045
|
return {
|
|
1012
1046
|
blankSlateText: view.options.blankSlateText,
|
|
1013
1047
|
colSpan: view.options.columns.length
|
|
@@ -1024,18 +1058,18 @@ __p += '<span class="label">\n</span>\n';
|
|
|
1024
1058
|
return __p
|
|
1025
1059
|
}
|
|
1026
1060
|
|
|
1027
|
-
|
|
1061
|
+
const TooltipView = Marionette.ItemView.extend({
|
|
1028
1062
|
template: template$3,
|
|
1029
1063
|
className: 'tooltip',
|
|
1030
1064
|
ui: {
|
|
1031
1065
|
label: '.label'
|
|
1032
1066
|
},
|
|
1033
|
-
hide: function
|
|
1067
|
+
hide: function () {
|
|
1034
1068
|
this.visible = false;
|
|
1035
1069
|
clearTimeout(this.timeout);
|
|
1036
1070
|
this.$el.removeClass('visible');
|
|
1037
1071
|
},
|
|
1038
|
-
show: function
|
|
1072
|
+
show: function (text, position, options) {
|
|
1039
1073
|
options = options || {};
|
|
1040
1074
|
this.visible = true;
|
|
1041
1075
|
clearTimeout(this.timeout);
|
|
@@ -1065,99 +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
|
-
update();
|
|
1138
|
-
function update() {
|
|
1139
|
-
updateMethod.call(view, view.getAttributeBoundOption(optionName, normalize));
|
|
1140
|
-
}
|
|
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
|
+
});
|
|
1141
1121
|
},
|
|
1142
|
-
getAttributeBoundOption
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
})
|
|
1152
|
-
if (bindingValueOptionName in this.options) {
|
|
1153
|
-
return value === this.options[bindingValueOptionName];
|
|
1154
|
-
} else if (typeof this.options[optionName] === 'function') {
|
|
1155
|
-
return normalize(this.options[optionName](value));
|
|
1156
|
-
} else if (optionName in this.options) {
|
|
1157
|
-
return normalize(this.options[optionName]);
|
|
1158
|
-
} else if (binding) {
|
|
1159
|
-
return normalize(value);
|
|
1160
|
-
}
|
|
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
|
+
});
|
|
1161
1132
|
}
|
|
1162
1133
|
};
|
|
1163
1134
|
|
|
@@ -1250,6 +1221,11 @@ var attributeBinding = {
|
|
|
1250
1221
|
* An array of prefixes to lookup translations for labels and
|
|
1251
1222
|
* inline help texts based on attribute names.
|
|
1252
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
|
+
*
|
|
1253
1229
|
* @param {string} [options.additionalInlineHelpText]
|
|
1254
1230
|
* A text that will be appended to the translation based inline
|
|
1255
1231
|
* text.
|
|
@@ -1295,7 +1271,8 @@ var attributeBinding = {
|
|
|
1295
1271
|
*
|
|
1296
1272
|
* @mixin
|
|
1297
1273
|
*/
|
|
1298
|
-
|
|
1274
|
+
const inputView = {
|
|
1275
|
+
...attributeBinding,
|
|
1299
1276
|
ui: {
|
|
1300
1277
|
label: 'label',
|
|
1301
1278
|
labelText: 'label .name',
|
|
@@ -1323,19 +1300,22 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
|
|
|
1323
1300
|
* @since 0.9
|
|
1324
1301
|
* @member
|
|
1325
1302
|
*/
|
|
1326
|
-
attributeTranslationKeys: function
|
|
1327
|
-
return attributeTranslationKeys(this.options.propertyName, keyName, _.extend({
|
|
1303
|
+
attributeTranslationKeys: function (keyName, options) {
|
|
1304
|
+
return attributeTranslationKeys(this.options.attributeTranslationPropertyName || this.options.propertyName, keyName, _.extend({
|
|
1328
1305
|
prefixes: this.options.attributeTranslationKeyPrefixes,
|
|
1329
1306
|
fallbackModelI18nKey: this.model.i18nKey
|
|
1330
1307
|
}, options || {}));
|
|
1331
1308
|
},
|
|
1332
|
-
onRender: function
|
|
1309
|
+
onRender: function () {
|
|
1333
1310
|
this.$el.addClass('input');
|
|
1334
1311
|
this.$el.addClass(this.model.modelName + '_' + this.options.propertyName);
|
|
1335
1312
|
this.$el.data('inputPropertyName', this.options.propertyName);
|
|
1336
1313
|
this.$el.data('labelText', this.labelText());
|
|
1337
1314
|
this.$el.data('inlineHelpText', this.inlineHelpText());
|
|
1338
1315
|
this.ui.labelText.text(this.labelText());
|
|
1316
|
+
if (this.options.hideLabel) {
|
|
1317
|
+
this.ui.label.addClass('visually_hidden');
|
|
1318
|
+
}
|
|
1339
1319
|
this.updateInlineHelp();
|
|
1340
1320
|
this.setLabelFor();
|
|
1341
1321
|
this.setupBooleanAttributeBinding('disabled', this.updateDisabled);
|
|
@@ -1345,15 +1325,15 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
|
|
|
1345
1325
|
* The label to display in the form.
|
|
1346
1326
|
* @return {string}
|
|
1347
1327
|
*/
|
|
1348
|
-
labelText: function
|
|
1328
|
+
labelText: function () {
|
|
1349
1329
|
return this.options.label || this.localizedAttributeName();
|
|
1350
1330
|
},
|
|
1351
|
-
localizedAttributeName: function
|
|
1331
|
+
localizedAttributeName: function () {
|
|
1352
1332
|
return findTranslation(this.attributeTranslationKeys('label', {
|
|
1353
1333
|
fallbackPrefix: 'activerecord.attributes'
|
|
1354
1334
|
}));
|
|
1355
1335
|
},
|
|
1356
|
-
updateInlineHelp: function
|
|
1336
|
+
updateInlineHelp: function () {
|
|
1357
1337
|
this.ui.inlineHelp.html(this.inlineHelpText());
|
|
1358
1338
|
if (!this.inlineHelpText()) {
|
|
1359
1339
|
this.ui.inlineHelp.hide();
|
|
@@ -1363,7 +1343,7 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
|
|
|
1363
1343
|
* The inline help text for the form field.
|
|
1364
1344
|
* @return {string}
|
|
1365
1345
|
*/
|
|
1366
|
-
inlineHelpText: function
|
|
1346
|
+
inlineHelpText: function () {
|
|
1367
1347
|
var keys = this.attributeTranslationKeys('inline_help', {
|
|
1368
1348
|
fallbackPrefix: 'pageflow.ui.inline_help'
|
|
1369
1349
|
});
|
|
@@ -1375,34 +1355,34 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
|
|
|
1375
1355
|
html: true
|
|
1376
1356
|
}), this.options.additionalInlineHelpText]).join(' ');
|
|
1377
1357
|
},
|
|
1378
|
-
setLabelFor
|
|
1358
|
+
setLabelFor() {
|
|
1379
1359
|
if (this.ui.input && this.ui.label.length === 1 && !this.ui.input.attr('id')) {
|
|
1380
|
-
|
|
1360
|
+
const id = 'input_' + this.model.modelName + '_' + this.options.propertyName;
|
|
1381
1361
|
this.ui.input.attr('id', id);
|
|
1382
1362
|
this.ui.label.attr('for', id);
|
|
1383
1363
|
}
|
|
1384
1364
|
},
|
|
1385
|
-
isDisabled: function
|
|
1365
|
+
isDisabled: function () {
|
|
1386
1366
|
return this.getBooleanAttributBoundOption('disabled');
|
|
1387
1367
|
},
|
|
1388
|
-
updateDisabled: function
|
|
1368
|
+
updateDisabled: function () {
|
|
1389
1369
|
this.$el.toggleClass('input-disabled', !!this.isDisabled());
|
|
1390
1370
|
this.updateInlineHelp();
|
|
1391
1371
|
if (this.ui.input) {
|
|
1392
1372
|
this.updateDisabledAttribute(this.ui.input);
|
|
1393
1373
|
}
|
|
1394
1374
|
},
|
|
1395
|
-
updateDisabledAttribute: function
|
|
1375
|
+
updateDisabledAttribute: function (element) {
|
|
1396
1376
|
if (this.isDisabled()) {
|
|
1397
1377
|
element.attr('disabled', true);
|
|
1398
1378
|
} else {
|
|
1399
1379
|
element.removeAttr('disabled');
|
|
1400
1380
|
}
|
|
1401
1381
|
},
|
|
1402
|
-
updateVisible: function
|
|
1382
|
+
updateVisible: function () {
|
|
1403
1383
|
this.$el.toggleClass('hidden_via_binding', this.getBooleanAttributBoundOption('visible') === false);
|
|
1404
1384
|
}
|
|
1405
|
-
}
|
|
1385
|
+
};
|
|
1406
1386
|
|
|
1407
1387
|
function template$4(data) {
|
|
1408
1388
|
var __p = '';
|
|
@@ -1418,7 +1398,7 @@ return __p
|
|
|
1418
1398
|
*
|
|
1419
1399
|
* @class
|
|
1420
1400
|
*/
|
|
1421
|
-
|
|
1401
|
+
const CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
1422
1402
|
mixins: [inputView],
|
|
1423
1403
|
template: template$4,
|
|
1424
1404
|
className: 'check_box_group_input',
|
|
@@ -1429,7 +1409,7 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
|
1429
1409
|
label: 'label',
|
|
1430
1410
|
container: '.check_boxes_container'
|
|
1431
1411
|
},
|
|
1432
|
-
initialize: function
|
|
1412
|
+
initialize: function () {
|
|
1433
1413
|
if (!this.options.texts) {
|
|
1434
1414
|
if (!this.options.translationKeys) {
|
|
1435
1415
|
var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
|
|
@@ -1444,26 +1424,26 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
|
|
|
1444
1424
|
});
|
|
1445
1425
|
}
|
|
1446
1426
|
},
|
|
1447
|
-
onRender: function
|
|
1427
|
+
onRender: function () {
|
|
1448
1428
|
this.ui.label.attr('for', this.cid);
|
|
1449
1429
|
this.appendOptions();
|
|
1450
1430
|
this.load();
|
|
1451
1431
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1452
1432
|
},
|
|
1453
|
-
appendOptions: function
|
|
1433
|
+
appendOptions: function () {
|
|
1454
1434
|
_.each(this.options.values, function (value, index) {
|
|
1455
1435
|
var option = '<div class="check_box">' + '<label><input type="checkbox" name="' + value + '" />' + this.options.texts[index] + '</label></div>';
|
|
1456
1436
|
this.ui.container.append($(option));
|
|
1457
1437
|
}, this);
|
|
1458
1438
|
},
|
|
1459
|
-
save: function
|
|
1439
|
+
save: function () {
|
|
1460
1440
|
var configured = {};
|
|
1461
1441
|
_.each(this.ui.container.find('input'), function (input) {
|
|
1462
1442
|
configured[$(input).attr('name')] = $(input).prop('checked');
|
|
1463
1443
|
});
|
|
1464
1444
|
this.model.set(this.options.propertyName, configured);
|
|
1465
1445
|
},
|
|
1466
|
-
load: function
|
|
1446
|
+
load: function () {
|
|
1467
1447
|
if (!this.isClosed) {
|
|
1468
1448
|
_.each(this.options.values, function (value) {
|
|
1469
1449
|
this.ui.container.find('input[name="' + value + '"]').prop('checked', this.model.get(this.options.propertyName)[value]);
|
|
@@ -1491,7 +1471,7 @@ return __p
|
|
|
1491
1471
|
*
|
|
1492
1472
|
* @class
|
|
1493
1473
|
*/
|
|
1494
|
-
|
|
1474
|
+
const UrlDisplayView = Marionette.ItemView.extend({
|
|
1495
1475
|
mixins: [inputView],
|
|
1496
1476
|
template: template$5,
|
|
1497
1477
|
ui: {
|
|
@@ -1501,43 +1481,21 @@ var UrlDisplayView = Marionette.ItemView.extend({
|
|
|
1501
1481
|
'change': 'update'
|
|
1502
1482
|
},
|
|
1503
1483
|
events: {
|
|
1504
|
-
'click a': function
|
|
1484
|
+
'click a': function (event) {
|
|
1505
1485
|
// Ensure default is not prevented by parent event listener.
|
|
1506
1486
|
event.stopPropagation();
|
|
1507
1487
|
}
|
|
1508
1488
|
},
|
|
1509
|
-
onRender: function
|
|
1489
|
+
onRender: function () {
|
|
1510
1490
|
this.update();
|
|
1511
1491
|
},
|
|
1512
|
-
update: function
|
|
1492
|
+
update: function () {
|
|
1513
1493
|
var url = this.model.get(this.options.propertyName || 'original_url');
|
|
1514
1494
|
this.$el.toggle(this.model.isUploaded() && !_.isEmpty(url));
|
|
1515
1495
|
this.ui.link.attr('href', url);
|
|
1516
1496
|
}
|
|
1517
1497
|
});
|
|
1518
1498
|
|
|
1519
|
-
function _classCallCheck(instance, Constructor) {
|
|
1520
|
-
if (!(instance instanceof Constructor)) {
|
|
1521
|
-
throw new TypeError("Cannot call a class as a function");
|
|
1522
|
-
}
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1525
|
-
function _defineProperties(target, props) {
|
|
1526
|
-
for (var i = 0; i < props.length; i++) {
|
|
1527
|
-
var descriptor = props[i];
|
|
1528
|
-
descriptor.enumerable = descriptor.enumerable || false;
|
|
1529
|
-
descriptor.configurable = true;
|
|
1530
|
-
if ("value" in descriptor) descriptor.writable = true;
|
|
1531
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
|
|
1535
|
-
function _createClass(Constructor, protoProps, staticProps) {
|
|
1536
|
-
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
1537
|
-
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
1538
|
-
return Constructor;
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
1499
|
/**
|
|
1542
1500
|
* Input view for a number.
|
|
1543
1501
|
*
|
|
@@ -1550,84 +1508,73 @@ function _createClass(Constructor, protoProps, staticProps) {
|
|
|
1550
1508
|
*
|
|
1551
1509
|
* @class
|
|
1552
1510
|
*/
|
|
1553
|
-
|
|
1511
|
+
const NumberInputView = Marionette.ItemView.extend({
|
|
1554
1512
|
mixins: [inputView],
|
|
1555
|
-
template:
|
|
1556
|
-
|
|
1557
|
-
|
|
1513
|
+
template: () => `
|
|
1514
|
+
<label>
|
|
1515
|
+
<span class="name"></span>
|
|
1516
|
+
<span class="inline_help"></span>
|
|
1517
|
+
</label>
|
|
1518
|
+
<input type="text" dir="auto" />
|
|
1519
|
+
`,
|
|
1558
1520
|
ui: {
|
|
1559
1521
|
input: 'input'
|
|
1560
1522
|
},
|
|
1561
1523
|
events: {
|
|
1562
1524
|
'change': 'onChange'
|
|
1563
1525
|
},
|
|
1564
|
-
initialize
|
|
1526
|
+
initialize() {
|
|
1565
1527
|
this.parser = new NumberParser(this.options.locale);
|
|
1566
1528
|
},
|
|
1567
|
-
onRender: function
|
|
1529
|
+
onRender: function () {
|
|
1568
1530
|
this.load();
|
|
1569
1531
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1570
1532
|
},
|
|
1571
|
-
onChange: function
|
|
1533
|
+
onChange: function () {
|
|
1572
1534
|
this.save();
|
|
1573
1535
|
this.load();
|
|
1574
1536
|
},
|
|
1575
|
-
onClose: function
|
|
1537
|
+
onClose: function () {
|
|
1576
1538
|
this.save();
|
|
1577
1539
|
},
|
|
1578
|
-
save: function
|
|
1579
|
-
|
|
1540
|
+
save: function () {
|
|
1541
|
+
const inputValue = this.ui.input.val();
|
|
1580
1542
|
this.model.set(this.options.propertyName, this.parser.parse(inputValue) || 0);
|
|
1581
1543
|
},
|
|
1582
|
-
load: function
|
|
1583
|
-
|
|
1584
|
-
|
|
1544
|
+
load: function () {
|
|
1545
|
+
const input = this.ui.input;
|
|
1546
|
+
const value = this.model.get(this.options.propertyName) || 0;
|
|
1585
1547
|
input.val(value.toLocaleString(this.options.locale, {
|
|
1586
1548
|
useGrouping: false
|
|
1587
1549
|
}));
|
|
1588
1550
|
},
|
|
1589
|
-
displayValidationError: function
|
|
1551
|
+
displayValidationError: function (message) {
|
|
1590
1552
|
this.$el.addClass('invalid');
|
|
1591
1553
|
this.ui.input.attr('title', message);
|
|
1592
1554
|
},
|
|
1593
|
-
resetValidationError: function
|
|
1555
|
+
resetValidationError: function (message) {
|
|
1594
1556
|
this.$el.removeClass('invalid');
|
|
1595
1557
|
this.ui.input.attr('title', '');
|
|
1596
1558
|
}
|
|
1597
1559
|
});
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
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({
|
|
1604
1565
|
length: 10
|
|
1605
|
-
}).map(
|
|
1606
|
-
|
|
1607
|
-
});
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
this._group = new RegExp("[".concat(parts.find(function (d) {
|
|
1612
|
-
return d.type === "group";
|
|
1613
|
-
}).value, "]"), "g");
|
|
1614
|
-
this._decimal = new RegExp("[".concat(parts.find(function (d) {
|
|
1615
|
-
return d.type === "decimal";
|
|
1616
|
-
}).value, "]"));
|
|
1617
|
-
this._numeral = new RegExp("[".concat(numerals.join(""), "]"), "g");
|
|
1618
|
-
this._index = function (d) {
|
|
1619
|
-
return index.get(d);
|
|
1620
|
-
};
|
|
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);
|
|
1621
1572
|
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
}
|
|
1628
|
-
}]);
|
|
1629
|
-
return NumberParser;
|
|
1630
|
-
}();
|
|
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
|
+
}
|
|
1631
1578
|
|
|
1632
1579
|
/**
|
|
1633
1580
|
* Text based input view that can display a placeholder.
|
|
@@ -1650,20 +1597,20 @@ var NumberParser = /*#__PURE__*/function () {
|
|
|
1650
1597
|
* Obtain placeholder by looking up the configured `propertyName`
|
|
1651
1598
|
* inside a given model.
|
|
1652
1599
|
*/
|
|
1653
|
-
|
|
1654
|
-
onRender: function
|
|
1600
|
+
const inputWithPlaceholderText = {
|
|
1601
|
+
onRender: function () {
|
|
1655
1602
|
this.updatePlaceholder();
|
|
1656
1603
|
if (this.options.placeholderBinding) {
|
|
1657
1604
|
this.listenTo(this.model, 'change:' + this.options.placeholderBinding, this.updatePlaceholder);
|
|
1658
1605
|
}
|
|
1659
1606
|
},
|
|
1660
|
-
updateDisabled: function
|
|
1607
|
+
updateDisabled: function () {
|
|
1661
1608
|
this.updatePlaceholder();
|
|
1662
1609
|
},
|
|
1663
|
-
updatePlaceholder: function
|
|
1610
|
+
updatePlaceholder: function () {
|
|
1664
1611
|
this.ui.input.attr('placeholder', this.placeholderText());
|
|
1665
1612
|
},
|
|
1666
|
-
placeholderText: function
|
|
1613
|
+
placeholderText: function () {
|
|
1667
1614
|
if (!this.isDisabled() || !this.options.hidePlaceholderIfDisabled) {
|
|
1668
1615
|
if (this.options.placeholder) {
|
|
1669
1616
|
if (typeof this.options.placeholder == 'function') {
|
|
@@ -1677,25 +1624,22 @@ var inputWithPlaceholderText = {
|
|
|
1677
1624
|
}
|
|
1678
1625
|
return '';
|
|
1679
1626
|
},
|
|
1680
|
-
placeholderModelValue: function
|
|
1627
|
+
placeholderModelValue: function () {
|
|
1681
1628
|
return this.options.placeholderModel && this.options.placeholderModel.get(this.options.propertyName);
|
|
1682
1629
|
}
|
|
1683
1630
|
};
|
|
1684
1631
|
|
|
1685
|
-
|
|
1686
|
-
onRender
|
|
1632
|
+
const viewWithValidationErrorMessages = {
|
|
1633
|
+
onRender() {
|
|
1687
1634
|
this.listenTo(this.model, 'invalid sync', this.updateValidationErrorMessages);
|
|
1688
1635
|
this.updateValidationErrorMessages();
|
|
1689
1636
|
},
|
|
1690
|
-
updateValidationErrorMessages
|
|
1691
|
-
|
|
1692
|
-
var errors = this.model.validationErrors && this.model.validationErrors[this.options.propertyName] || [];
|
|
1637
|
+
updateValidationErrorMessages() {
|
|
1638
|
+
const errors = this.model.validationErrors && this.model.validationErrors[this.options.propertyName] || [];
|
|
1693
1639
|
if (errors.length) {
|
|
1694
1640
|
this.validationErrorList = this.validationErrorList || $('<ul class="validation_error_messages" />').appendTo(this.el);
|
|
1695
1641
|
this.validationErrorList.html('');
|
|
1696
|
-
errors.forEach(
|
|
1697
|
-
return _this.validationErrorList.append("<li>".concat(error, "</li>"));
|
|
1698
|
-
});
|
|
1642
|
+
errors.forEach(error => this.validationErrorList.append(`<li>${error}</li>`));
|
|
1699
1643
|
this.$el.addClass('invalid');
|
|
1700
1644
|
} else if (this.validationErrorList) {
|
|
1701
1645
|
this.validationErrorList.remove();
|
|
@@ -1730,7 +1674,7 @@ return __p
|
|
|
1730
1674
|
*
|
|
1731
1675
|
* @class
|
|
1732
1676
|
*/
|
|
1733
|
-
|
|
1677
|
+
const TextInputView = Marionette.ItemView.extend({
|
|
1734
1678
|
mixins: [inputView, inputWithPlaceholderText, viewWithValidationErrorMessages],
|
|
1735
1679
|
template: template$6,
|
|
1736
1680
|
ui: {
|
|
@@ -1739,25 +1683,25 @@ var TextInputView = Marionette.ItemView.extend({
|
|
|
1739
1683
|
events: {
|
|
1740
1684
|
'change': 'onChange'
|
|
1741
1685
|
},
|
|
1742
|
-
onRender: function
|
|
1686
|
+
onRender: function () {
|
|
1743
1687
|
this.load();
|
|
1744
1688
|
this.validate();
|
|
1745
1689
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1746
1690
|
},
|
|
1747
|
-
onChange: function
|
|
1691
|
+
onChange: function () {
|
|
1748
1692
|
if (this.validate()) {
|
|
1749
1693
|
this.save();
|
|
1750
1694
|
}
|
|
1751
1695
|
},
|
|
1752
|
-
onClose: function
|
|
1696
|
+
onClose: function () {
|
|
1753
1697
|
if (this.validate()) {
|
|
1754
1698
|
this.save();
|
|
1755
1699
|
}
|
|
1756
1700
|
},
|
|
1757
|
-
save: function
|
|
1701
|
+
save: function () {
|
|
1758
1702
|
this.model.set(this.options.propertyName, this.ui.input.val());
|
|
1759
1703
|
},
|
|
1760
|
-
load: function
|
|
1704
|
+
load: function () {
|
|
1761
1705
|
var input = this.ui.input;
|
|
1762
1706
|
input.val(this.model.get(this.options.propertyName));
|
|
1763
1707
|
|
|
@@ -1767,7 +1711,7 @@ var TextInputView = Marionette.ItemView.extend({
|
|
|
1767
1711
|
// for new and maxLength-conforming data: add validation
|
|
1768
1712
|
this.validateMaxLength = input.val().length <= this.options.maxLength;
|
|
1769
1713
|
},
|
|
1770
|
-
validate: function
|
|
1714
|
+
validate: function () {
|
|
1771
1715
|
var input = this.ui.input;
|
|
1772
1716
|
if (this.options.required && !input.val()) {
|
|
1773
1717
|
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.required_field'));
|
|
@@ -1783,11 +1727,11 @@ var TextInputView = Marionette.ItemView.extend({
|
|
|
1783
1727
|
return true;
|
|
1784
1728
|
}
|
|
1785
1729
|
},
|
|
1786
|
-
displayValidationError: function
|
|
1730
|
+
displayValidationError: function (message) {
|
|
1787
1731
|
this.$el.addClass('invalid');
|
|
1788
1732
|
this.ui.input.attr('title', message);
|
|
1789
1733
|
},
|
|
1790
|
-
resetValidationError: function
|
|
1734
|
+
resetValidationError: function (message) {
|
|
1791
1735
|
this.$el.removeClass('invalid');
|
|
1792
1736
|
this.ui.input.attr('title', '');
|
|
1793
1737
|
}
|
|
@@ -1799,31 +1743,640 @@ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></spa
|
|
|
1799
1743
|
return __p
|
|
1800
1744
|
}
|
|
1801
1745
|
|
|
1802
|
-
|
|
1746
|
+
const FileNameInputView = TextInputView.extend({
|
|
1803
1747
|
template: template$7,
|
|
1804
1748
|
className: 'file_name_input',
|
|
1805
1749
|
ui: Object.assign({}, TextInputView.prototype.ui, {
|
|
1806
1750
|
extension: '.file_name_input-extension'
|
|
1807
1751
|
}),
|
|
1808
|
-
onRender: function
|
|
1752
|
+
onRender: function () {
|
|
1809
1753
|
TextInputView.prototype.onRender.call(this);
|
|
1810
1754
|
},
|
|
1811
|
-
save: function
|
|
1812
|
-
|
|
1813
|
-
|
|
1755
|
+
save: function () {
|
|
1756
|
+
const baseName = this.ui.input.val();
|
|
1757
|
+
const extension = this.ui.extension.text();
|
|
1814
1758
|
this.model.set(this.options.propertyName, baseName + extension);
|
|
1815
1759
|
},
|
|
1816
|
-
load: function
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
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] : '';
|
|
1821
1765
|
this.ui.input.val(baseName);
|
|
1822
1766
|
this.ui.extension.text(extension);
|
|
1823
1767
|
this.options.maxLength = this.options.maxLength || 255;
|
|
1824
1768
|
}
|
|
1825
1769
|
});
|
|
1826
1770
|
|
|
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
|
+
}
|
|
1826
|
+
|
|
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
|
+
});
|
|
1896
|
+
});
|
|
1897
|
+
}
|
|
1898
|
+
|
|
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;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
// Event wiring
|
|
2064
|
+
|
|
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
|
+
|
|
1827
2380
|
function template$8(data) {
|
|
1828
2381
|
var __p = '';
|
|
1829
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';
|
|
@@ -1858,75 +2411,75 @@ return __p
|
|
|
1858
2411
|
* is used as placeholderColor option, it will be passed the value of the
|
|
1859
2412
|
* placeholderColorBinding attribute each time it changes.
|
|
1860
2413
|
*
|
|
1861
|
-
* @param {
|
|
1862
|
-
*
|
|
1863
|
-
*
|
|
1864
|
-
*
|
|
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.
|
|
1865
2427
|
*
|
|
1866
2428
|
* @class
|
|
1867
2429
|
*/
|
|
1868
|
-
|
|
2430
|
+
const ColorInputView = Marionette.ItemView.extend({
|
|
1869
2431
|
mixins: [inputView, inputWithPlaceholderText],
|
|
1870
2432
|
template: template$8,
|
|
1871
2433
|
className: 'color_input',
|
|
1872
2434
|
ui: {
|
|
1873
2435
|
input: 'input'
|
|
1874
2436
|
},
|
|
1875
|
-
|
|
1876
|
-
'mousedown': 'refreshPicker'
|
|
1877
|
-
},
|
|
1878
|
-
onRender: function onRender() {
|
|
2437
|
+
onRender: function () {
|
|
1879
2438
|
this.setupAttributeBinding('placeholderColor', this.updatePlaceholderColor);
|
|
1880
|
-
this.ui.input
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
this.model.set(this.options.propertyName, color);
|
|
1888
|
-
}
|
|
1889
|
-
this._saving = false;
|
|
1890
|
-
}, this)
|
|
2439
|
+
this._colorPicker = new ColorPicker(this.ui.input[0], {
|
|
2440
|
+
alpha: this.options.alpha,
|
|
2441
|
+
defaultValue: this.defaultValue(),
|
|
2442
|
+
fallbackColor: this.getAttributeBoundOption('placeholderColor'),
|
|
2443
|
+
fallbackColorDescription: this.options.placeholderColorDescription,
|
|
2444
|
+
swatches: this.getSwatches(),
|
|
2445
|
+
onChange: this._debouncedOnChange()
|
|
1891
2446
|
});
|
|
1892
2447
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
1893
2448
|
if (this.options.defaultValueBinding) {
|
|
1894
2449
|
this.listenTo(this.model, 'change:' + this.options.defaultValueBinding, this.updateSettings);
|
|
1895
2450
|
}
|
|
1896
|
-
this.
|
|
2451
|
+
this.load();
|
|
1897
2452
|
},
|
|
1898
|
-
updatePlaceholderColor
|
|
1899
|
-
this.
|
|
2453
|
+
updatePlaceholderColor(value) {
|
|
2454
|
+
if (this._colorPicker) {
|
|
2455
|
+
this._colorPicker.update({
|
|
2456
|
+
fallbackColor: value
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
1900
2459
|
},
|
|
1901
|
-
updateSettings: function
|
|
1902
|
-
this.
|
|
1903
|
-
this.ui.input.minicolors('settings', {
|
|
2460
|
+
updateSettings: function () {
|
|
2461
|
+
this._colorPicker.update({
|
|
1904
2462
|
defaultValue: this.defaultValue(),
|
|
1905
2463
|
swatches: this.getSwatches()
|
|
1906
2464
|
});
|
|
1907
2465
|
this.load();
|
|
1908
2466
|
},
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
var settings = this.ui.input.data('minicolors-settings');
|
|
1912
|
-
if (settings) {
|
|
1913
|
-
delete settings.swatches;
|
|
1914
|
-
this.ui.input.data('minicolors-settings', settings);
|
|
1915
|
-
}
|
|
1916
|
-
},
|
|
1917
|
-
load: function load() {
|
|
2467
|
+
load: function () {
|
|
2468
|
+
var color = this.model.get(this.options.propertyName) || this.defaultValue() || '';
|
|
1918
2469
|
if (!this._saving) {
|
|
1919
|
-
this.
|
|
2470
|
+
this._colorPicker.setValue(color);
|
|
1920
2471
|
}
|
|
1921
2472
|
this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
|
|
1922
2473
|
},
|
|
1923
|
-
|
|
1924
|
-
this.
|
|
2474
|
+
onBeforeClose: function () {
|
|
2475
|
+
this._colorPicker.destroy();
|
|
1925
2476
|
},
|
|
1926
|
-
getSwatches: function
|
|
1927
|
-
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();
|
|
1928
2481
|
},
|
|
1929
|
-
defaultValue: function
|
|
2482
|
+
defaultValue: function () {
|
|
1930
2483
|
var bindingValue;
|
|
1931
2484
|
if (this.options.defaultValueBinding) {
|
|
1932
2485
|
bindingValue = this.model.get(this.options.defaultValueBinding);
|
|
@@ -1938,6 +2491,19 @@ var ColorInputView = Marionette.ItemView.extend({
|
|
|
1938
2491
|
} else {
|
|
1939
2492
|
return bindingValue;
|
|
1940
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;
|
|
1941
2507
|
}
|
|
1942
2508
|
});
|
|
1943
2509
|
|
|
@@ -1953,8 +2519,9 @@ return __p
|
|
|
1953
2519
|
*
|
|
1954
2520
|
* @param {Object} [options]
|
|
1955
2521
|
*
|
|
1956
|
-
* @param {string[]} [options.values]
|
|
1957
|
-
* 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.
|
|
1958
2525
|
*
|
|
1959
2526
|
* @param {number} [options.defaultValue]
|
|
1960
2527
|
* Default value to display if property is not set.
|
|
@@ -2031,7 +2598,7 @@ return __p
|
|
|
2031
2598
|
*
|
|
2032
2599
|
* @class
|
|
2033
2600
|
*/
|
|
2034
|
-
|
|
2601
|
+
const SelectInputView = Marionette.ItemView.extend({
|
|
2035
2602
|
mixins: [inputView],
|
|
2036
2603
|
template: template$9,
|
|
2037
2604
|
events: {
|
|
@@ -2041,7 +2608,8 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2041
2608
|
select: 'select',
|
|
2042
2609
|
input: 'select'
|
|
2043
2610
|
},
|
|
2044
|
-
initialize: function
|
|
2611
|
+
initialize: function () {
|
|
2612
|
+
this.options.values = _.result(this.options, 'values');
|
|
2045
2613
|
if (this.options.collection) {
|
|
2046
2614
|
this.options.values = _.pluck(this.options.collection, this.options.valueProperty);
|
|
2047
2615
|
if (this.options.textProperty) {
|
|
@@ -2075,7 +2643,7 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2075
2643
|
}
|
|
2076
2644
|
this.optGroups = {};
|
|
2077
2645
|
},
|
|
2078
|
-
onRender: function
|
|
2646
|
+
onRender: function () {
|
|
2079
2647
|
this.appendBlank();
|
|
2080
2648
|
this.appendPlaceholder();
|
|
2081
2649
|
this.appendOptions();
|
|
@@ -2085,7 +2653,7 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2085
2653
|
this.save();
|
|
2086
2654
|
}
|
|
2087
2655
|
},
|
|
2088
|
-
appendBlank: function
|
|
2656
|
+
appendBlank: function () {
|
|
2089
2657
|
if (!this.options.includeBlank) {
|
|
2090
2658
|
return;
|
|
2091
2659
|
}
|
|
@@ -2102,7 +2670,7 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2102
2670
|
option.text = blankText;
|
|
2103
2671
|
this.ui.select.append(option);
|
|
2104
2672
|
},
|
|
2105
|
-
appendPlaceholder: function
|
|
2673
|
+
appendPlaceholder: function () {
|
|
2106
2674
|
if (!this.options.placeholderModel && !this.options.placeholderValue) {
|
|
2107
2675
|
return;
|
|
2108
2676
|
}
|
|
@@ -2117,7 +2685,7 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2117
2685
|
this.ui.select.append(option);
|
|
2118
2686
|
}
|
|
2119
2687
|
},
|
|
2120
|
-
appendOptions: function
|
|
2688
|
+
appendOptions: function () {
|
|
2121
2689
|
_.each(this.options.values, function (value, index) {
|
|
2122
2690
|
var option = document.createElement('option');
|
|
2123
2691
|
var group = this.options.groups[index];
|
|
@@ -2134,7 +2702,7 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2134
2702
|
}
|
|
2135
2703
|
}, this);
|
|
2136
2704
|
},
|
|
2137
|
-
findOrCreateOptGroup: function
|
|
2705
|
+
findOrCreateOptGroup: function (label) {
|
|
2138
2706
|
if (!this.optGroups[label]) {
|
|
2139
2707
|
this.optGroups[label] = $('<optgroup />', {
|
|
2140
2708
|
label: label
|
|
@@ -2142,15 +2710,15 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2142
2710
|
}
|
|
2143
2711
|
return this.optGroups[label];
|
|
2144
2712
|
},
|
|
2145
|
-
save: function
|
|
2146
|
-
|
|
2713
|
+
save: function () {
|
|
2714
|
+
const value = this.ui.select.val();
|
|
2147
2715
|
if ('defaultValue' in this.options && value === this.options.defaultValue) {
|
|
2148
2716
|
this.model.unset(this.options.propertyName);
|
|
2149
2717
|
} else {
|
|
2150
2718
|
this.model.set(this.options.propertyName, value);
|
|
2151
2719
|
}
|
|
2152
2720
|
},
|
|
2153
|
-
load: function
|
|
2721
|
+
load: function () {
|
|
2154
2722
|
if (!this.isClosed) {
|
|
2155
2723
|
var value = this.model.get(this.options.propertyName);
|
|
2156
2724
|
if (this.model.has(this.options.propertyName) && this.ui.select.find('option[value="' + value + '"]:not([disabled])').length) {
|
|
@@ -2164,9 +2732,9 @@ var SelectInputView = Marionette.ItemView.extend({
|
|
|
2164
2732
|
}
|
|
2165
2733
|
});
|
|
2166
2734
|
|
|
2167
|
-
|
|
2735
|
+
const ExtendedSelectInputView = SelectInputView.extend({
|
|
2168
2736
|
className: 'extended_select_input',
|
|
2169
|
-
initialize: function
|
|
2737
|
+
initialize: function () {
|
|
2170
2738
|
SelectInputView.prototype.initialize.apply(this, arguments);
|
|
2171
2739
|
if (this.options.collection) {
|
|
2172
2740
|
if (this.options.descriptionProperty) {
|
|
@@ -2181,18 +2749,18 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2181
2749
|
});
|
|
2182
2750
|
}
|
|
2183
2751
|
},
|
|
2184
|
-
onRender: function
|
|
2752
|
+
onRender: function () {
|
|
2185
2753
|
var view = this,
|
|
2186
2754
|
options = this.options;
|
|
2187
2755
|
SelectInputView.prototype.onRender.apply(this, arguments);
|
|
2188
2756
|
$.widget("custom.extendedselectmenu", $.ui.selectmenu, {
|
|
2189
|
-
_renderItem: function
|
|
2757
|
+
_renderItem: function (ul, item) {
|
|
2190
2758
|
var widget = this;
|
|
2191
2759
|
var li = $('<li>', {
|
|
2192
|
-
|
|
2760
|
+
class: item.value
|
|
2193
2761
|
});
|
|
2194
2762
|
var container = $('<div>', {
|
|
2195
|
-
|
|
2763
|
+
class: 'text-container'
|
|
2196
2764
|
}).appendTo(li);
|
|
2197
2765
|
var index = options.values.indexOf(item.value);
|
|
2198
2766
|
if (item.disabled) {
|
|
@@ -2200,16 +2768,16 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2200
2768
|
}
|
|
2201
2769
|
if (options.pictogramClass) {
|
|
2202
2770
|
$('<span>', {
|
|
2203
|
-
|
|
2771
|
+
class: options.pictogramClass
|
|
2204
2772
|
}).prependTo(li);
|
|
2205
2773
|
}
|
|
2206
2774
|
$('<p>', {
|
|
2207
2775
|
text: item.label,
|
|
2208
|
-
|
|
2776
|
+
class: 'item-text'
|
|
2209
2777
|
}).appendTo(container);
|
|
2210
2778
|
$('<p>', {
|
|
2211
2779
|
text: options.descriptions[index],
|
|
2212
|
-
|
|
2780
|
+
class: 'item-description'
|
|
2213
2781
|
}).appendTo(container);
|
|
2214
2782
|
if (options.helpLinkClicked) {
|
|
2215
2783
|
$('<a>', {
|
|
@@ -2223,7 +2791,7 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2223
2791
|
}
|
|
2224
2792
|
return li.appendTo(ul);
|
|
2225
2793
|
},
|
|
2226
|
-
_resizeMenu: function
|
|
2794
|
+
_resizeMenu: function () {
|
|
2227
2795
|
this.menuWrap.addClass('extended_select_input_menu');
|
|
2228
2796
|
var menuHeight = this.menu.height(),
|
|
2229
2797
|
menuOffset = this.button.offset().top + this.button.outerHeight(),
|
|
@@ -2249,7 +2817,7 @@ var ExtendedSelectInputView = SelectInputView.extend({
|
|
|
2249
2817
|
}
|
|
2250
2818
|
});
|
|
2251
2819
|
},
|
|
2252
|
-
select: function
|
|
2820
|
+
select: function (event, ui) {
|
|
2253
2821
|
this.ui.select.val(ui.item.value);
|
|
2254
2822
|
this.save();
|
|
2255
2823
|
}
|
|
@@ -2312,7 +2880,7 @@ return __p
|
|
|
2312
2880
|
*
|
|
2313
2881
|
* @class
|
|
2314
2882
|
*/
|
|
2315
|
-
|
|
2883
|
+
const TextAreaInputView = Marionette.ItemView.extend({
|
|
2316
2884
|
mixins: [inputView, inputWithPlaceholderText],
|
|
2317
2885
|
template: template$a,
|
|
2318
2886
|
className: 'text_area_input',
|
|
@@ -2338,7 +2906,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2338
2906
|
'change .open_in_new_tab': 'setTargetFromOpenInNewTabCheckBox',
|
|
2339
2907
|
'change .display_url': 'setUrlFromDisplayUrl'
|
|
2340
2908
|
},
|
|
2341
|
-
onRender: function
|
|
2909
|
+
onRender: function () {
|
|
2342
2910
|
this.ui.input.addClass(this.options.size);
|
|
2343
2911
|
this.load();
|
|
2344
2912
|
this.updatePlaceholder();
|
|
@@ -2407,16 +2975,26 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2407
2975
|
this.editor.on('change', _.bind(this.save, this));
|
|
2408
2976
|
this.editor.on('aftercommand:composer', _.bind(this.save, this));
|
|
2409
2977
|
},
|
|
2410
|
-
onClose: function
|
|
2978
|
+
onClose: function () {
|
|
2411
2979
|
this.editor.fire('destroy:composer');
|
|
2412
2980
|
},
|
|
2413
|
-
|
|
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 () {
|
|
2414
2992
|
this.model.set(this.options.propertyName, this.editor.getValue());
|
|
2415
2993
|
},
|
|
2416
|
-
load: function
|
|
2994
|
+
load: function () {
|
|
2417
2995
|
this.ui.input.val(this.model.get(this.options.propertyName));
|
|
2418
2996
|
},
|
|
2419
|
-
setupUrlLinkPanel: function
|
|
2997
|
+
setupUrlLinkPanel: function () {
|
|
2420
2998
|
this.editor.on('show:dialog', _.bind(function () {
|
|
2421
2999
|
this.ui.linkDialog.toggleClass('for_existing_link', this.ui.linkButton.hasClass('wysihtml5-command-active'));
|
|
2422
3000
|
var currentUrl = this.ui.urlInput.val();
|
|
@@ -2429,7 +3007,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2429
3007
|
}
|
|
2430
3008
|
}, this));
|
|
2431
3009
|
},
|
|
2432
|
-
setupFragmentLinkPanel: function
|
|
3010
|
+
setupFragmentLinkPanel: function () {
|
|
2433
3011
|
if (this.options.fragmentLinkInputView) {
|
|
2434
3012
|
this.fragmentLinkModel = new Backbone.Model();
|
|
2435
3013
|
this.listenTo(this.fragmentLinkModel, 'change', function (model, options) {
|
|
@@ -2457,7 +3035,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2457
3035
|
this.ui.fragmentLinkPanel.hide();
|
|
2458
3036
|
}
|
|
2459
3037
|
},
|
|
2460
|
-
initLinkTypePanels: function
|
|
3038
|
+
initLinkTypePanels: function (isUrlLink) {
|
|
2461
3039
|
if (isUrlLink) {
|
|
2462
3040
|
this.ui.urlLinkRadioButton.prop('checked', true);
|
|
2463
3041
|
} else {
|
|
@@ -2465,23 +3043,23 @@ var TextAreaInputView = Marionette.ItemView.extend({
|
|
|
2465
3043
|
}
|
|
2466
3044
|
this.ui.toolbar.toggleClass('fragment_link_panel_active', !isUrlLink);
|
|
2467
3045
|
},
|
|
2468
|
-
showUrlLinkPanel: function
|
|
3046
|
+
showUrlLinkPanel: function () {
|
|
2469
3047
|
this.ui.toolbar.removeClass('fragment_link_panel_active');
|
|
2470
3048
|
this.setUrlFromDisplayUrl();
|
|
2471
3049
|
this.setTargetFromOpenInNewTabCheckBox();
|
|
2472
3050
|
},
|
|
2473
|
-
showFragmentLinkPanel: function
|
|
3051
|
+
showFragmentLinkPanel: function () {
|
|
2474
3052
|
this.ui.toolbar.addClass('fragment_link_panel_active');
|
|
2475
3053
|
this.setInputsFromFragmentLinkModel();
|
|
2476
3054
|
},
|
|
2477
|
-
setInputsFromFragmentLinkModel: function
|
|
3055
|
+
setInputsFromFragmentLinkModel: function () {
|
|
2478
3056
|
this.ui.urlInput.val('#' + (this.fragmentLinkModel.get('linkId') || ''));
|
|
2479
3057
|
this.ui.targetInput.val('_self');
|
|
2480
3058
|
},
|
|
2481
|
-
setUrlFromDisplayUrl: function
|
|
3059
|
+
setUrlFromDisplayUrl: function () {
|
|
2482
3060
|
this.ui.urlInput.val(this.ui.displayUrlInput.val());
|
|
2483
3061
|
},
|
|
2484
|
-
setTargetFromOpenInNewTabCheckBox: function
|
|
3062
|
+
setTargetFromOpenInNewTabCheckBox: function () {
|
|
2485
3063
|
this.ui.targetInput.val(this.ui.openInNewTabCheckBox.is(':checked') ? '_blank' : '_self');
|
|
2486
3064
|
}
|
|
2487
3065
|
});
|
|
@@ -2509,7 +3087,7 @@ return __p
|
|
|
2509
3087
|
*
|
|
2510
3088
|
* @class
|
|
2511
3089
|
*/
|
|
2512
|
-
|
|
3090
|
+
const UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype */{
|
|
2513
3091
|
mixins: [inputView],
|
|
2514
3092
|
template: template$b,
|
|
2515
3093
|
ui: {
|
|
@@ -2519,74 +3097,85 @@ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype *
|
|
|
2519
3097
|
events: {
|
|
2520
3098
|
'change': 'onChange'
|
|
2521
3099
|
},
|
|
2522
|
-
onRender: function
|
|
3100
|
+
onRender: function () {
|
|
2523
3101
|
this.ui.validation.hide();
|
|
2524
3102
|
this.load();
|
|
2525
3103
|
this.validate();
|
|
3104
|
+
this.listenTo(this.model, 'change:' + this.options.displayPropertyName, this.load);
|
|
2526
3105
|
},
|
|
2527
|
-
onChange: function
|
|
2528
|
-
var
|
|
2529
|
-
this.validate().then(
|
|
2530
|
-
return _this.save();
|
|
2531
|
-
}, function () {
|
|
2532
|
-
return _this.saveDisplayProperty();
|
|
2533
|
-
});
|
|
3106
|
+
onChange: function () {
|
|
3107
|
+
var value = this.ui.input.val();
|
|
3108
|
+
this.validate().then(() => this.save(value), () => this.saveDisplayProperty(value));
|
|
2534
3109
|
},
|
|
2535
|
-
saveDisplayProperty: function
|
|
3110
|
+
saveDisplayProperty: function (value) {
|
|
2536
3111
|
this.model.unset(this.options.propertyName, {
|
|
2537
3112
|
silent: true
|
|
2538
3113
|
});
|
|
2539
|
-
this.model.set(this.options.displayPropertyName,
|
|
3114
|
+
this.model.set(this.options.displayPropertyName, value);
|
|
2540
3115
|
},
|
|
2541
|
-
save: function
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
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
|
+
});
|
|
2546
3122
|
});
|
|
2547
3123
|
},
|
|
2548
|
-
load: function
|
|
3124
|
+
load: function () {
|
|
2549
3125
|
this.ui.input.val(this.model.has(this.options.displayPropertyName) ? this.model.get(this.options.displayPropertyName) : this.model.get(this.options.propertyName));
|
|
2550
3126
|
this.onLoad();
|
|
2551
3127
|
},
|
|
2552
3128
|
/**
|
|
2553
3129
|
* Override to be notified when the input has been loaded.
|
|
2554
3130
|
*/
|
|
2555
|
-
onLoad: function
|
|
3131
|
+
onLoad: function () {},
|
|
2556
3132
|
/**
|
|
2557
3133
|
* Override to validate the untransformed url. Validation error
|
|
2558
3134
|
* message can be passed as rejected promise. Progress notifications
|
|
2559
3135
|
* are displayed. Only valid urls are stored in the configuration.
|
|
2560
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
|
+
*
|
|
2561
3141
|
* @return Promise
|
|
2562
3142
|
*/
|
|
2563
|
-
validateUrl: function
|
|
3143
|
+
validateUrl: function (url) {
|
|
2564
3144
|
return $.Deferred().resolve().promise();
|
|
2565
3145
|
},
|
|
2566
3146
|
/**
|
|
2567
3147
|
* Override to transform the property value before it is stored.
|
|
2568
3148
|
*
|
|
3149
|
+
* @param {String} value - The URL value to transform
|
|
3150
|
+
* @param {*} validationResult - Optional result returned by validateUrl
|
|
2569
3151
|
* @return Promise | String
|
|
2570
3152
|
*/
|
|
2571
|
-
transformPropertyValue: function
|
|
3153
|
+
transformPropertyValue: function (value, validationResult) {
|
|
2572
3154
|
return value;
|
|
2573
3155
|
},
|
|
2574
3156
|
/**
|
|
2575
3157
|
* Override to change the list of supported host names.
|
|
2576
3158
|
*/
|
|
2577
|
-
supportedHosts: function
|
|
3159
|
+
supportedHosts: function () {
|
|
2578
3160
|
return this.options.supportedHosts;
|
|
2579
3161
|
},
|
|
3162
|
+
/**
|
|
3163
|
+
* Override to enable HTTPS URLs by default.
|
|
3164
|
+
* @return {boolean}
|
|
3165
|
+
*/
|
|
3166
|
+
permitHttps: function () {
|
|
3167
|
+
return this.options.permitHttps;
|
|
3168
|
+
},
|
|
2580
3169
|
// Host names used to be expected to include protocols. Remove
|
|
2581
3170
|
// protocols for backwards compatilbity. Since supportedHosts
|
|
2582
3171
|
// is supposed to be overridden in subclasses, we do it in a
|
|
2583
3172
|
// separate method.
|
|
2584
|
-
supportedHostsWithoutLegacyProtocols: function
|
|
3173
|
+
supportedHostsWithoutLegacyProtocols: function () {
|
|
2585
3174
|
return _.map(this.supportedHosts(), function (host) {
|
|
2586
3175
|
return host.replace(/^https?:\/\//, '');
|
|
2587
3176
|
});
|
|
2588
3177
|
},
|
|
2589
|
-
validate: function
|
|
3178
|
+
validate: function (success) {
|
|
2590
3179
|
var view = this;
|
|
2591
3180
|
var options = this.options;
|
|
2592
3181
|
var value = this.ui.input.val();
|
|
@@ -2594,7 +3183,7 @@ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype *
|
|
|
2594
3183
|
displayValidationError(I18n$1.t('pageflow.ui.views.inputs.url_input_view.required_field'));
|
|
2595
3184
|
} else if (value && !isValidUrl(value)) {
|
|
2596
3185
|
var errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint');
|
|
2597
|
-
if (
|
|
3186
|
+
if (view.permitHttps()) {
|
|
2598
3187
|
errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint_https');
|
|
2599
3188
|
}
|
|
2600
3189
|
displayValidationError(errorMessage);
|
|
@@ -2604,16 +3193,24 @@ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype *
|
|
|
2604
3193
|
}).join(''));
|
|
2605
3194
|
} else {
|
|
2606
3195
|
return view.validateUrl(value).progress(function (message) {
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
3196
|
+
if (!view.isClosed) {
|
|
3197
|
+
displayValidationPending(message);
|
|
3198
|
+
}
|
|
3199
|
+
}).done(function (result) {
|
|
3200
|
+
view.lastValidationResult = result;
|
|
3201
|
+
if (!view.isClosed) {
|
|
3202
|
+
resetValidationError();
|
|
3203
|
+
}
|
|
2610
3204
|
}).fail(function (error) {
|
|
2611
|
-
|
|
3205
|
+
view.lastValidationResult = undefined;
|
|
3206
|
+
if (!view.isClosed) {
|
|
3207
|
+
displayValidationError(error);
|
|
3208
|
+
}
|
|
2612
3209
|
});
|
|
2613
3210
|
}
|
|
2614
3211
|
return $.Deferred().reject().promise();
|
|
2615
3212
|
function isValidUrl(url) {
|
|
2616
|
-
return
|
|
3213
|
+
return view.permitHttps() ? url.match(/^https?:\/\//i) : url.match(/^http:\/\//i);
|
|
2617
3214
|
}
|
|
2618
3215
|
function hasSupportedHost(url) {
|
|
2619
3216
|
return _.any(view.supportedHostsWithoutLegacyProtocols(), function (host) {
|
|
@@ -2633,6 +3230,7 @@ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype *
|
|
|
2633
3230
|
function resetValidationError(message) {
|
|
2634
3231
|
view.$el.removeClass('invalid');
|
|
2635
3232
|
view.ui.input.attr('aria-invalid', 'false');
|
|
3233
|
+
view.ui.validation.text('');
|
|
2636
3234
|
view.ui.validation.hide();
|
|
2637
3235
|
}
|
|
2638
3236
|
}
|
|
@@ -2684,9 +3282,9 @@ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype *
|
|
|
2684
3282
|
*
|
|
2685
3283
|
* @class
|
|
2686
3284
|
*/
|
|
2687
|
-
|
|
3285
|
+
const ProxyUrlInputView = UrlInputView.extend( /** @lends ProxyUrlInputView.prototype */{
|
|
2688
3286
|
// @override
|
|
2689
|
-
validateUrl: function
|
|
3287
|
+
validateUrl: function (url) {
|
|
2690
3288
|
var view = this;
|
|
2691
3289
|
return $.Deferred(function (deferred) {
|
|
2692
3290
|
deferred.notify(I18n$1.t('pageflow.ui.views.inputs.proxy_url_input_view.url_validation'));
|
|
@@ -2701,14 +3299,14 @@ var ProxyUrlInputView = UrlInputView.extend( /** @lends ProxyUrlInputView.protot
|
|
|
2701
3299
|
}).promise();
|
|
2702
3300
|
},
|
|
2703
3301
|
// override
|
|
2704
|
-
transformPropertyValue: function
|
|
3302
|
+
transformPropertyValue: function (url) {
|
|
2705
3303
|
return this.rewriteUrl(url);
|
|
2706
3304
|
},
|
|
2707
3305
|
// override
|
|
2708
|
-
supportedHosts: function
|
|
3306
|
+
supportedHosts: function () {
|
|
2709
3307
|
return _.pluck(this.options.proxies, 'url');
|
|
2710
3308
|
},
|
|
2711
|
-
rewriteUrl: function
|
|
3309
|
+
rewriteUrl: function (url) {
|
|
2712
3310
|
_.each(this.options.proxies, function (proxy) {
|
|
2713
3311
|
url = url.replace(new RegExp('^' + proxy.url + '/?'), proxy.base_path + '/');
|
|
2714
3312
|
});
|
|
@@ -2717,8 +3315,12 @@ var ProxyUrlInputView = UrlInputView.extend( /** @lends ProxyUrlInputView.protot
|
|
|
2717
3315
|
});
|
|
2718
3316
|
|
|
2719
3317
|
function template$c(data) {
|
|
2720
|
-
var __p = '';
|
|
2721
|
-
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="
|
|
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';
|
|
2722
3324
|
return __p
|
|
2723
3325
|
}
|
|
2724
3326
|
|
|
@@ -2747,39 +3349,48 @@ return __p
|
|
|
2747
3349
|
* Already update the model while dragging the handle - not only after
|
|
2748
3350
|
* handle has been released.
|
|
2749
3351
|
*
|
|
3352
|
+
* @param {string} [options.icon]
|
|
3353
|
+
* Path to an icon image to display before the label.
|
|
3354
|
+
*
|
|
2750
3355
|
* @class
|
|
2751
3356
|
*/
|
|
2752
|
-
|
|
3357
|
+
const SliderInputView = Marionette.ItemView.extend({
|
|
2753
3358
|
mixins: [inputView],
|
|
2754
3359
|
className: 'slider_input',
|
|
2755
3360
|
template: template$c,
|
|
3361
|
+
serializeData() {
|
|
3362
|
+
return {
|
|
3363
|
+
icon: this.options.icon
|
|
3364
|
+
};
|
|
3365
|
+
},
|
|
2756
3366
|
ui: {
|
|
2757
3367
|
widget: '.slider',
|
|
2758
3368
|
value: '.value'
|
|
2759
3369
|
},
|
|
2760
3370
|
events: {
|
|
3371
|
+
'slidestart': 'handleSlideStart',
|
|
2761
3372
|
'slidechange': 'save',
|
|
2762
3373
|
'slide': 'handleSlide'
|
|
2763
3374
|
},
|
|
2764
|
-
onRender: function
|
|
2765
|
-
var _this = this;
|
|
3375
|
+
onRender: function () {
|
|
2766
3376
|
this.ui.widget.slider({
|
|
2767
3377
|
animate: 'fast'
|
|
2768
3378
|
});
|
|
2769
|
-
this.
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
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
|
+
}
|
|
2775
3386
|
this.load();
|
|
2776
3387
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2777
3388
|
},
|
|
2778
|
-
updateSliderOption
|
|
3389
|
+
updateSliderOption(name, value) {
|
|
2779
3390
|
this.ui.widget.slider('option', name, value);
|
|
2780
3391
|
this.updateText(this.ui.widget.slider('value'));
|
|
2781
3392
|
},
|
|
2782
|
-
updateDisabled: function
|
|
3393
|
+
updateDisabled: function (disabled) {
|
|
2783
3394
|
this.$el.toggleClass('disabled', !!disabled);
|
|
2784
3395
|
if (disabled) {
|
|
2785
3396
|
this.ui.widget.slider('disable');
|
|
@@ -2787,33 +3398,54 @@ var SliderInputView = Marionette.ItemView.extend({
|
|
|
2787
3398
|
this.ui.widget.slider('enable');
|
|
2788
3399
|
}
|
|
2789
3400
|
},
|
|
2790
|
-
|
|
2791
|
-
this.
|
|
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);
|
|
2792
3409
|
if (this.options.saveOnSlide) {
|
|
2793
3410
|
this.save(event, ui);
|
|
2794
3411
|
}
|
|
2795
3412
|
},
|
|
2796
|
-
save: function
|
|
2797
|
-
|
|
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);
|
|
2798
3419
|
},
|
|
2799
|
-
load: function
|
|
3420
|
+
load: function () {
|
|
2800
3421
|
var value;
|
|
2801
3422
|
if (this.model.has(this.options.propertyName)) {
|
|
2802
3423
|
value = this.model.get(this.options.propertyName);
|
|
2803
3424
|
} else {
|
|
2804
3425
|
value = 'defaultValue' in this.options ? this.options.defaultValue : 0;
|
|
2805
3426
|
}
|
|
2806
|
-
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;
|
|
2807
3431
|
this.updateText(value);
|
|
2808
3432
|
},
|
|
2809
|
-
clampValue
|
|
2810
|
-
|
|
2811
|
-
|
|
3433
|
+
clampValue(value) {
|
|
3434
|
+
const min = this.ui.widget.slider('option', 'min');
|
|
3435
|
+
const max = this.ui.widget.slider('option', 'max');
|
|
2812
3436
|
return Math.min(max, Math.max(min, value));
|
|
2813
3437
|
},
|
|
2814
|
-
updateText: function
|
|
2815
|
-
var
|
|
2816
|
-
|
|
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
|
+
}
|
|
2817
3449
|
this.ui.value.text(text);
|
|
2818
3450
|
}
|
|
2819
3451
|
});
|
|
@@ -2824,7 +3456,7 @@ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></spa
|
|
|
2824
3456
|
return __p
|
|
2825
3457
|
}
|
|
2826
3458
|
|
|
2827
|
-
|
|
3459
|
+
const JsonInputView = Marionette.ItemView.extend({
|
|
2828
3460
|
mixins: [inputView],
|
|
2829
3461
|
template: template$d,
|
|
2830
3462
|
className: 'json_input',
|
|
@@ -2835,30 +3467,30 @@ var JsonInputView = Marionette.ItemView.extend({
|
|
|
2835
3467
|
'change': 'onChange',
|
|
2836
3468
|
'keyup': 'validate'
|
|
2837
3469
|
},
|
|
2838
|
-
onRender: function
|
|
3470
|
+
onRender: function () {
|
|
2839
3471
|
this.load();
|
|
2840
3472
|
this.validate();
|
|
2841
3473
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2842
3474
|
},
|
|
2843
|
-
onChange: function
|
|
3475
|
+
onChange: function () {
|
|
2844
3476
|
if (this.validate()) {
|
|
2845
3477
|
this.save();
|
|
2846
3478
|
}
|
|
2847
3479
|
},
|
|
2848
|
-
onClose: function
|
|
3480
|
+
onClose: function () {
|
|
2849
3481
|
if (this.validate()) {
|
|
2850
3482
|
this.save();
|
|
2851
3483
|
}
|
|
2852
3484
|
},
|
|
2853
|
-
save: function
|
|
3485
|
+
save: function () {
|
|
2854
3486
|
this.model.set(this.options.propertyName, this.ui.input.val() ? JSON.parse(this.ui.input.val()) : null);
|
|
2855
3487
|
},
|
|
2856
|
-
load: function
|
|
3488
|
+
load: function () {
|
|
2857
3489
|
var input = this.ui.input;
|
|
2858
3490
|
var value = this.model.get(this.options.propertyName);
|
|
2859
3491
|
input.val(value ? JSON.stringify(value, null, 2) : '');
|
|
2860
3492
|
},
|
|
2861
|
-
validate: function
|
|
3493
|
+
validate: function () {
|
|
2862
3494
|
var input = this.ui.input;
|
|
2863
3495
|
if (input.val() && !this.isValidJson(input.val())) {
|
|
2864
3496
|
this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.json_input_view.invalid'));
|
|
@@ -2868,15 +3500,15 @@ var JsonInputView = Marionette.ItemView.extend({
|
|
|
2868
3500
|
return true;
|
|
2869
3501
|
}
|
|
2870
3502
|
},
|
|
2871
|
-
displayValidationError: function
|
|
3503
|
+
displayValidationError: function (message) {
|
|
2872
3504
|
this.$el.addClass('invalid');
|
|
2873
3505
|
this.ui.input.attr('title', message);
|
|
2874
3506
|
},
|
|
2875
|
-
resetValidationError: function
|
|
3507
|
+
resetValidationError: function (message) {
|
|
2876
3508
|
this.$el.removeClass('invalid');
|
|
2877
3509
|
this.ui.input.attr('title', '');
|
|
2878
3510
|
},
|
|
2879
|
-
isValidJson: function
|
|
3511
|
+
isValidJson: function (text) {
|
|
2880
3512
|
try {
|
|
2881
3513
|
JSON.parse(text);
|
|
2882
3514
|
return true;
|
|
@@ -2913,7 +3545,7 @@ return __p
|
|
|
2913
3545
|
*
|
|
2914
3546
|
* @class
|
|
2915
3547
|
*/
|
|
2916
|
-
|
|
3548
|
+
const CheckBoxInputView = Marionette.ItemView.extend({
|
|
2917
3549
|
mixins: [inputView],
|
|
2918
3550
|
template: template$e,
|
|
2919
3551
|
className: 'check_box_input',
|
|
@@ -2924,18 +3556,18 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2924
3556
|
input: 'input',
|
|
2925
3557
|
label: 'label'
|
|
2926
3558
|
},
|
|
2927
|
-
onRender: function
|
|
3559
|
+
onRender: function () {
|
|
2928
3560
|
this.ui.label.attr('for', this.cid);
|
|
2929
3561
|
this.ui.input.attr('id', this.cid);
|
|
2930
3562
|
this.load();
|
|
2931
3563
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
|
|
2932
3564
|
},
|
|
2933
|
-
updateDisabled: function
|
|
3565
|
+
updateDisabled: function () {
|
|
2934
3566
|
this.load();
|
|
2935
3567
|
},
|
|
2936
|
-
save: function
|
|
3568
|
+
save: function () {
|
|
2937
3569
|
if (!this.isDisabled()) {
|
|
2938
|
-
|
|
3570
|
+
const value = this.ui.input.is(':checked');
|
|
2939
3571
|
if (this.options.storeInverted) {
|
|
2940
3572
|
this.model.set(this.options.storeInverted, !value);
|
|
2941
3573
|
} else {
|
|
@@ -2943,12 +3575,12 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2943
3575
|
}
|
|
2944
3576
|
}
|
|
2945
3577
|
},
|
|
2946
|
-
load: function
|
|
3578
|
+
load: function () {
|
|
2947
3579
|
if (!this.isClosed) {
|
|
2948
3580
|
this.ui.input.prop('checked', !!this.displayValue());
|
|
2949
3581
|
}
|
|
2950
3582
|
},
|
|
2951
|
-
displayValue: function
|
|
3583
|
+
displayValue: function () {
|
|
2952
3584
|
if (this.isDisabled() && this.options.displayUncheckedIfDisabled) {
|
|
2953
3585
|
return false;
|
|
2954
3586
|
} else if (this.isDisabled() && this.options.displayCheckedIfDisabled) {
|
|
@@ -2961,6 +3593,86 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2961
3593
|
}
|
|
2962
3594
|
});
|
|
2963
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
|
+
|
|
2964
3676
|
/**
|
|
2965
3677
|
* Render a separator in a {@link ConfigurationEditorView} tab.
|
|
2966
3678
|
*
|
|
@@ -2970,7 +3682,7 @@ var CheckBoxInputView = Marionette.ItemView.extend({
|
|
|
2970
3682
|
*
|
|
2971
3683
|
* @class
|
|
2972
3684
|
*/
|
|
2973
|
-
|
|
3685
|
+
const SeparatorView = Marionette.View.extend({
|
|
2974
3686
|
className: 'separator'
|
|
2975
3687
|
});
|
|
2976
3688
|
|
|
@@ -2982,11 +3694,14 @@ var SeparatorView = Marionette.View.extend({
|
|
|
2982
3694
|
*
|
|
2983
3695
|
* @class
|
|
2984
3696
|
*/
|
|
2985
|
-
|
|
3697
|
+
const LabelOnlyView = Marionette.ItemView.extend({
|
|
2986
3698
|
mixins: [inputView],
|
|
2987
|
-
template:
|
|
2988
|
-
|
|
2989
|
-
|
|
3699
|
+
template: () => `
|
|
3700
|
+
<label>
|
|
3701
|
+
<span class="name"></span>
|
|
3702
|
+
<span class="inline_help"></span>
|
|
3703
|
+
</label>
|
|
3704
|
+
`,
|
|
2990
3705
|
ui: {
|
|
2991
3706
|
label: 'label'
|
|
2992
3707
|
}
|
|
@@ -3007,9 +3722,9 @@ var LabelOnlyView = Marionette.ItemView.extend({
|
|
|
3007
3722
|
*
|
|
3008
3723
|
* @since 12.0
|
|
3009
3724
|
*/
|
|
3010
|
-
|
|
3725
|
+
const EnumTableCellView = TableCellView.extend({
|
|
3011
3726
|
className: 'enum_table_cell',
|
|
3012
|
-
update: function
|
|
3727
|
+
update: function () {
|
|
3013
3728
|
this.$el.text(this.attributeTranslation('cell_text.' + (this.attributeValue() || 'blank')));
|
|
3014
3729
|
this.$el.attr('title', this.attributeTranslation('cell_title.' + (this.attributeValue() || 'blank'), {
|
|
3015
3730
|
defaultValue: ''
|
|
@@ -3047,7 +3762,7 @@ return __p
|
|
|
3047
3762
|
*
|
|
3048
3763
|
* @since 12.0
|
|
3049
3764
|
*/
|
|
3050
|
-
|
|
3765
|
+
const DeleteRowTableCellView = TableCellView.extend({
|
|
3051
3766
|
className: 'delete_row_table_cell',
|
|
3052
3767
|
template: template$f,
|
|
3053
3768
|
ui: {
|
|
@@ -3055,11 +3770,11 @@ var DeleteRowTableCellView = TableCellView.extend({
|
|
|
3055
3770
|
},
|
|
3056
3771
|
events: {
|
|
3057
3772
|
'click .remove': 'destroy',
|
|
3058
|
-
'click': function
|
|
3773
|
+
'click': function () {
|
|
3059
3774
|
return false;
|
|
3060
3775
|
}
|
|
3061
3776
|
},
|
|
3062
|
-
showButton: function
|
|
3777
|
+
showButton: function () {
|
|
3063
3778
|
if (this.options.toggleDeleteButton) {
|
|
3064
3779
|
var context = this.getModel();
|
|
3065
3780
|
var toggle = context[this.options.toggleDeleteButton].apply(context);
|
|
@@ -3072,11 +3787,11 @@ var DeleteRowTableCellView = TableCellView.extend({
|
|
|
3072
3787
|
return true;
|
|
3073
3788
|
}
|
|
3074
3789
|
},
|
|
3075
|
-
update: function
|
|
3790
|
+
update: function () {
|
|
3076
3791
|
this.ui.removeButton.toggleClass('remove', this.showButton());
|
|
3077
3792
|
this.ui.removeButton.attr('title', this.attributeTranslation('cell_title'));
|
|
3078
3793
|
},
|
|
3079
|
-
destroy: function
|
|
3794
|
+
destroy: function () {
|
|
3080
3795
|
this.getModel().destroy();
|
|
3081
3796
|
}
|
|
3082
3797
|
});
|
|
@@ -3097,9 +3812,9 @@ var DeleteRowTableCellView = TableCellView.extend({
|
|
|
3097
3812
|
*
|
|
3098
3813
|
* @since 12.0
|
|
3099
3814
|
*/
|
|
3100
|
-
|
|
3815
|
+
const PresenceTableCellView = TableCellView.extend({
|
|
3101
3816
|
className: 'presence_table_cell',
|
|
3102
|
-
update: function
|
|
3817
|
+
update: function () {
|
|
3103
3818
|
var isPresent = !!this.attributeValue();
|
|
3104
3819
|
this.$el.attr('title', isPresent ? this.attributeTranslation('cell_title.present', {
|
|
3105
3820
|
value: this.attributeValue()
|
|
@@ -3120,17 +3835,18 @@ var PresenceTableCellView = TableCellView.extend({
|
|
|
3120
3835
|
*
|
|
3121
3836
|
* @param {Object} [options]
|
|
3122
3837
|
*
|
|
3123
|
-
* @param {string[]} [options.icons]
|
|
3838
|
+
* @param {string[]|function} [options.icons]
|
|
3124
3839
|
* An array of all possible attribute values to be mapped to HTML
|
|
3125
3840
|
* classes of the same name. A global mapping from those classes to
|
|
3126
3841
|
* icon mixins is provided in
|
|
3127
|
-
* 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.
|
|
3128
3844
|
*
|
|
3129
3845
|
* @since 12.0
|
|
3130
3846
|
*/
|
|
3131
|
-
|
|
3847
|
+
const IconTableCellView = TableCellView.extend({
|
|
3132
3848
|
className: 'icon_table_cell',
|
|
3133
|
-
update: function
|
|
3849
|
+
update: function () {
|
|
3134
3850
|
var icon = this.attributeValue();
|
|
3135
3851
|
var isPresent = !!this.attributeValue();
|
|
3136
3852
|
this.removeExistingIcons();
|
|
@@ -3139,8 +3855,8 @@ var IconTableCellView = TableCellView.extend({
|
|
|
3139
3855
|
}) : this.attributeTranslation('cell_title.blank'));
|
|
3140
3856
|
this.$el.addClass(icon);
|
|
3141
3857
|
},
|
|
3142
|
-
removeExistingIcons: function
|
|
3143
|
-
this.$el.removeClass(this.options
|
|
3858
|
+
removeExistingIcons: function () {
|
|
3859
|
+
this.$el.removeClass(_.result(this.options, 'icons').join(' '));
|
|
3144
3860
|
}
|
|
3145
3861
|
});
|
|
3146
3862
|
|
|
@@ -3163,15 +3879,15 @@ var IconTableCellView = TableCellView.extend({
|
|
|
3163
3879
|
*
|
|
3164
3880
|
* @since 12.0
|
|
3165
3881
|
*/
|
|
3166
|
-
|
|
3882
|
+
const TextTableCellView = TableCellView.extend({
|
|
3167
3883
|
className: 'text_table_cell',
|
|
3168
|
-
update: function
|
|
3884
|
+
update: function () {
|
|
3169
3885
|
this.$el.text(this._updateText());
|
|
3170
3886
|
},
|
|
3171
|
-
_updateText: function
|
|
3887
|
+
_updateText: function () {
|
|
3172
3888
|
if (this.attributeValue()) {
|
|
3173
3889
|
return this.attributeValue();
|
|
3174
|
-
} else if (typeof this.options.column
|
|
3890
|
+
} else if (typeof this.options.column.default === 'function') {
|
|
3175
3891
|
var options = {};
|
|
3176
3892
|
if (this.options.column.contentBinding) {
|
|
3177
3893
|
options = {
|
|
@@ -3179,27 +3895,27 @@ var TextTableCellView = TableCellView.extend({
|
|
|
3179
3895
|
model: this.getModel()
|
|
3180
3896
|
};
|
|
3181
3897
|
}
|
|
3182
|
-
return this.options.column
|
|
3898
|
+
return this.options.column.default(options);
|
|
3183
3899
|
} else if ('default' in this.options.column) {
|
|
3184
|
-
return this.options.column
|
|
3900
|
+
return this.options.column.default;
|
|
3185
3901
|
} else {
|
|
3186
3902
|
return I18n$1.t('pageflow.ui.text_table_cell_view.empty');
|
|
3187
3903
|
}
|
|
3188
3904
|
}
|
|
3189
3905
|
});
|
|
3190
3906
|
|
|
3191
|
-
|
|
3192
|
-
subview: function
|
|
3907
|
+
const subviewContainer = {
|
|
3908
|
+
subview: function (view) {
|
|
3193
3909
|
this.subviews = this.subviews || new ChildViewContainer();
|
|
3194
3910
|
this.subviews.add(view.render());
|
|
3195
3911
|
return view;
|
|
3196
3912
|
},
|
|
3197
|
-
appendSubview: function
|
|
3198
|
-
|
|
3199
|
-
|
|
3913
|
+
appendSubview: function (view, {
|
|
3914
|
+
to
|
|
3915
|
+
} = {}) {
|
|
3200
3916
|
return (to || this.$el).append(this.subview(view).el);
|
|
3201
3917
|
},
|
|
3202
|
-
onClose: function
|
|
3918
|
+
onClose: function () {
|
|
3203
3919
|
if (this.subviews) {
|
|
3204
3920
|
this.subviews.call('close');
|
|
3205
3921
|
}
|
|
@@ -3209,9 +3925,9 @@ if (!Marionette.View.prototype.appendSubview) {
|
|
|
3209
3925
|
Cocktail.mixin(Marionette.View, subviewContainer);
|
|
3210
3926
|
}
|
|
3211
3927
|
|
|
3212
|
-
|
|
3928
|
+
const tooltipContainer = {
|
|
3213
3929
|
events: {
|
|
3214
|
-
'mouseover [data-tooltip]': function
|
|
3930
|
+
'mouseover [data-tooltip]': function (event) {
|
|
3215
3931
|
if (!this.tooltip.visible) {
|
|
3216
3932
|
var target = $(event.currentTarget);
|
|
3217
3933
|
var key = target.attr('data-tooltip');
|
|
@@ -3242,13 +3958,13 @@ var tooltipContainer = {
|
|
|
3242
3958
|
});
|
|
3243
3959
|
}
|
|
3244
3960
|
},
|
|
3245
|
-
'mouseleave [data-tooltip]': function
|
|
3961
|
+
'mouseleave [data-tooltip]': function () {
|
|
3246
3962
|
this.tooltip.hide();
|
|
3247
3963
|
}
|
|
3248
3964
|
},
|
|
3249
|
-
onRender: function
|
|
3965
|
+
onRender: function () {
|
|
3250
3966
|
this.appendSubview(this.tooltip = new TooltipView());
|
|
3251
3967
|
}
|
|
3252
3968
|
};
|
|
3253
3969
|
|
|
3254
|
-
export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, FileNameInputView, 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 };
|