pageflow 17.0.5 → 17.1.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.
Files changed (488) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +362 -35
  3. data/README.md +0 -1
  4. data/admins/pageflow/accounts.rb +16 -14
  5. data/admins/pageflow/entry.rb +68 -20
  6. data/admins/pageflow/entry_templates.rb +10 -9
  7. data/admins/pageflow/folder.rb +1 -1
  8. data/admins/pageflow/membership.rb +4 -4
  9. data/admins/pageflow/revisions.rb +5 -5
  10. data/admins/pageflow/site_root_entry.rb +64 -0
  11. data/admins/pageflow/sites.rb +12 -3
  12. data/admins/pageflow/translations.rb +75 -0
  13. data/admins/pageflow/user.rb +21 -35
  14. data/app/assets/javascripts/pageflow/admin/entries.js +30 -5
  15. data/app/assets/javascripts/pageflow/dist/ui.js +2865 -257
  16. data/app/assets/stylesheets/pageflow/admin/entries/index_table.scss +2 -1
  17. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +2 -1
  18. data/app/assets/stylesheets/pageflow/editor/background_positioning.scss +6 -0
  19. data/app/assets/stylesheets/pageflow/editor/base.scss +2 -0
  20. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +7 -1
  21. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +5 -1
  22. data/app/assets/stylesheets/pageflow/editor/files.scss +28 -16
  23. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +24 -0
  24. data/app/assets/stylesheets/pageflow/editor/info_box.scss +11 -3
  25. data/app/assets/stylesheets/pageflow/editor/list.scss +6 -4
  26. data/app/assets/stylesheets/pageflow/editor/list_search_field.scss +52 -0
  27. data/app/assets/stylesheets/pageflow/editor/outline.scss +0 -13
  28. data/app/assets/stylesheets/pageflow/editor/select_button.scss +1 -1
  29. data/app/assets/stylesheets/pageflow/editor/sortable.scss +12 -0
  30. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +4 -4
  31. data/app/assets/stylesheets/pageflow/ui/forms.scss +4 -0
  32. data/app/assets/stylesheets/pageflow/ui/input/color_input.scss +8 -0
  33. data/app/assets/stylesheets/pageflow/ui/input/file_name_input.scss +37 -0
  34. data/app/assets/stylesheets/pageflow/ui/properties.scss +5 -0
  35. data/app/assets/stylesheets/pageflow/ui.scss +1 -0
  36. data/app/controllers/concerns/pageflow/controller_delegation.rb +1 -1
  37. data/app/controllers/concerns/pageflow/edit_locking.rb +17 -10
  38. data/app/controllers/concerns/pageflow/entry_password_protection.rb +1 -0
  39. data/app/controllers/concerns/pageflow/public_https_mode.rb +2 -1
  40. data/app/controllers/concerns/pageflow/quota_verification.rb +5 -4
  41. data/app/controllers/pageflow/admin/initial_passwords_controller.rb +1 -0
  42. data/app/controllers/pageflow/application_controller.rb +19 -19
  43. data/app/controllers/pageflow/chapters_controller.rb +3 -2
  44. data/app/controllers/pageflow/edit_locks_controller.rb +3 -2
  45. data/app/controllers/pageflow/editor/encoding_confirmations_controller.rb +1 -0
  46. data/app/controllers/pageflow/editor/entries_controller.rb +2 -1
  47. data/app/controllers/pageflow/editor/entry_publications_controller.rb +1 -0
  48. data/app/controllers/pageflow/editor/file_import_controller.rb +3 -3
  49. data/app/controllers/pageflow/editor/files_controller.rb +7 -6
  50. data/app/controllers/pageflow/editor/widgets_controller.rb +1 -0
  51. data/app/controllers/pageflow/entries_controller.rb +77 -17
  52. data/app/controllers/pageflow/feeds_controller.rb +1 -1
  53. data/app/controllers/pageflow/files_controller.rb +1 -0
  54. data/app/controllers/pageflow/pages_controller.rb +4 -2
  55. data/app/controllers/pageflow/revisions_controller.rb +2 -1
  56. data/app/controllers/pageflow/sitemaps_controller.rb +1 -1
  57. data/app/controllers/pageflow/storylines_controller.rb +1 -0
  58. data/app/helpers/pageflow/admin/cutoff_modes_helper.rb +12 -0
  59. data/app/helpers/pageflow/admin/entries_helper.rb +1 -1
  60. data/app/helpers/pageflow/admin/entry_translations_helper.rb +18 -0
  61. data/app/helpers/pageflow/admin/features_helper.rb +1 -1
  62. data/app/helpers/pageflow/admin/form_helper.rb +3 -3
  63. data/app/helpers/pageflow/admin/locales_helper.rb +10 -2
  64. data/app/helpers/pageflow/admin/memberships_helper.rb +32 -32
  65. data/app/helpers/pageflow/admin/revisions_helper.rb +1 -1
  66. data/app/helpers/pageflow/admin/sites_helper.rb +22 -0
  67. data/app/helpers/pageflow/admin/users_helper.rb +7 -5
  68. data/app/helpers/pageflow/admin/widgets_helper.rb +3 -3
  69. data/app/helpers/pageflow/asset_urls_helper.rb +1 -1
  70. data/app/helpers/pageflow/audio_files_helper.rb +5 -2
  71. data/app/helpers/pageflow/background_image_helper.rb +7 -6
  72. data/app/helpers/pageflow/common_entry_seed_helper.rb +2 -4
  73. data/app/helpers/pageflow/editor/config_helper.rb +1 -1
  74. data/app/helpers/pageflow/editor/files_helper.rb +1 -1
  75. data/app/helpers/pageflow/embed_code_helper.rb +3 -3
  76. data/app/helpers/pageflow/entries_helper.rb +58 -34
  77. data/app/helpers/pageflow/entry_json_seed_helper.rb +3 -2
  78. data/app/helpers/pageflow/feeds_helper.rb +2 -2
  79. data/app/helpers/pageflow/file_background_images_helper.rb +2 -2
  80. data/app/helpers/pageflow/file_thumbnails_helper.rb +4 -3
  81. data/app/helpers/pageflow/files_helper.rb +5 -4
  82. data/app/helpers/pageflow/folders_helper.rb +8 -5
  83. data/app/helpers/pageflow/help_entries_helper.rb +2 -2
  84. data/app/helpers/pageflow/hreflang_links_helper.rb +37 -0
  85. data/app/helpers/pageflow/info_box_helper.rb +7 -11
  86. data/app/helpers/pageflow/media_query_helper.rb +3 -3
  87. data/app/helpers/pageflow/navigation_bar_helper.rb +1 -1
  88. data/app/helpers/pageflow/overview_helper.rb +1 -1
  89. data/app/helpers/pageflow/page_types_helper.rb +5 -5
  90. data/app/helpers/pageflow/pages_helper.rb +29 -15
  91. data/app/helpers/pageflow/public_i18n_helper.rb +1 -1
  92. data/app/helpers/pageflow/quota_helper.rb +4 -4
  93. data/app/helpers/pageflow/render_json_helper.rb +6 -3
  94. data/app/helpers/pageflow/revision_file_helper.rb +2 -1
  95. data/app/helpers/pageflow/sites_helper.rb +3 -3
  96. data/app/helpers/pageflow/social_share_helper.rb +24 -10
  97. data/app/helpers/pageflow/social_share_links_helper.rb +12 -9
  98. data/app/helpers/pageflow/structured_data_helper.rb +1 -1
  99. data/app/helpers/pageflow/stub_page_configuration.rb +7 -3
  100. data/app/helpers/pageflow/text_direction_helper.rb +1 -1
  101. data/app/helpers/pageflow/themes_helper.rb +1 -1
  102. data/app/helpers/pageflow/video_files_helper.rb +29 -13
  103. data/app/helpers/pageflow/widgets_helper.rb +7 -6
  104. data/app/inputs/pageflow_permalink_input.rb +3 -2
  105. data/app/jobs/pageflow/application_job.rb +1 -0
  106. data/app/jobs/pageflow/entry_export_import/upload_and_publish_file_job.rb +1 -1
  107. data/app/jobs/pageflow/poll_meta_data_from_zencoder_job.rb +1 -0
  108. data/app/jobs/pageflow/poll_zencoder_job.rb +3 -2
  109. data/app/jobs/pageflow/process_image_or_text_track_job.rb +1 -0
  110. data/app/jobs/pageflow/prune_auto_snapshots_job.rb +1 -0
  111. data/app/jobs/pageflow/request_meta_data_from_zencoder_job.rb +1 -0
  112. data/app/jobs/pageflow/submit_file_to_zencoder_job.rb +1 -0
  113. data/app/mailers/pageflow/user_mailer.rb +1 -0
  114. data/app/models/concerns/pageflow/auto_generated_perma_id.rb +13 -1
  115. data/app/models/concerns/pageflow/entry_publication_states.rb +7 -3
  116. data/app/models/concerns/pageflow/feature_target.rb +8 -4
  117. data/app/models/concerns/pageflow/output_source.rb +3 -3
  118. data/app/models/concerns/pageflow/permalinkable.rb +2 -1
  119. data/app/models/concerns/pageflow/reusable_file.rb +23 -23
  120. data/app/models/concerns/pageflow/serialization_blacklist.rb +1 -1
  121. data/app/models/concerns/pageflow/suspendable.rb +5 -3
  122. data/app/models/concerns/pageflow/theme_referencer.rb +1 -1
  123. data/app/models/concerns/pageflow/translatable.rb +62 -0
  124. data/app/models/concerns/pageflow/uploadable_file.rb +6 -6
  125. data/app/models/pageflow/account.rb +6 -5
  126. data/app/models/pageflow/account_member_query.rb +1 -1
  127. data/app/models/pageflow/account_role_query.rb +1 -1
  128. data/app/models/pageflow/application_query.rb +1 -1
  129. data/app/models/pageflow/application_record.rb +1 -1
  130. data/app/models/pageflow/audio_file.rb +4 -4
  131. data/app/models/pageflow/audio_file_url_templates.rb +1 -1
  132. data/app/models/pageflow/authentication_token.rb +2 -2
  133. data/app/models/pageflow/chapter.rb +6 -1
  134. data/app/models/pageflow/chapter_scaffold.rb +2 -4
  135. data/app/models/pageflow/cname_site_request_scope.rb +1 -1
  136. data/app/models/pageflow/customized_theme.rb +6 -6
  137. data/app/models/pageflow/draft_entry.rb +37 -9
  138. data/app/models/pageflow/edit_lock.rb +19 -21
  139. data/app/models/pageflow/encoding_confirmation.rb +2 -2
  140. data/app/models/pageflow/entries_feed.rb +2 -2
  141. data/app/models/pageflow/entry.rb +44 -30
  142. data/app/models/pageflow/entry_at_revision.rb +5 -1
  143. data/app/models/pageflow/entry_duplicate.rb +8 -5
  144. data/app/models/pageflow/entry_publication.rb +2 -2
  145. data/app/models/pageflow/entry_role_query.rb +4 -4
  146. data/app/models/pageflow/entry_template.rb +4 -4
  147. data/app/models/pageflow/entry_title_or_account_name_query.rb +2 -2
  148. data/app/models/pageflow/entry_translation_group.rb +42 -0
  149. data/app/models/pageflow/file_reuse.rb +2 -2
  150. data/app/models/pageflow/file_usage.rb +10 -3
  151. data/app/models/pageflow/folder.rb +2 -2
  152. data/app/models/pageflow/home_button.rb +7 -7
  153. data/app/models/pageflow/image_file.rb +20 -5
  154. data/app/models/pageflow/image_file_url_templates.rb +1 -1
  155. data/app/models/pageflow/invitation_form.rb +2 -1
  156. data/app/models/pageflow/managed_user_query.rb +1 -1
  157. data/app/models/pageflow/membership.rb +5 -5
  158. data/app/models/pageflow/nested_revision_component_copy.rb +263 -0
  159. data/app/models/pageflow/null_user.rb +1 -1
  160. data/app/models/pageflow/overview_button.rb +1 -1
  161. data/app/models/pageflow/page.rb +7 -3
  162. data/app/models/pageflow/permalink.rb +23 -2
  163. data/app/models/pageflow/permalink_directory.rb +7 -0
  164. data/app/models/pageflow/permalink_redirect.rb +7 -0
  165. data/app/models/pageflow/positioned_file.rb +5 -5
  166. data/app/models/pageflow/potential_entry_translations.rb +55 -0
  167. data/app/models/pageflow/potential_memberships.rb +5 -4
  168. data/app/models/pageflow/published_entry.rb +62 -11
  169. data/app/models/pageflow/revision.rb +24 -15
  170. data/app/models/pageflow/roles.rb +14 -18
  171. data/app/models/pageflow/site.rb +36 -3
  172. data/app/models/pageflow/site_root_entry_form.rb +27 -0
  173. data/app/models/pageflow/sitemaps.rb +10 -1
  174. data/app/models/pageflow/storyline.rb +5 -2
  175. data/app/models/pageflow/storyline_scaffold.rb +1 -1
  176. data/app/models/pageflow/text_track_file.rb +1 -1
  177. data/app/models/pageflow/text_track_file_url_templates.rb +1 -1
  178. data/app/models/pageflow/theme_customization_file.rb +3 -2
  179. data/app/models/pageflow/thumbnail_file_resolver.rb +1 -1
  180. data/app/models/pageflow/url_template.rb +1 -1
  181. data/app/models/pageflow/used_file.rb +7 -3
  182. data/app/models/pageflow/user_name_query.rb +2 -2
  183. data/app/models/pageflow/video_file.rb +22 -15
  184. data/app/models/pageflow/video_file_url_templates.rb +6 -4
  185. data/app/models/pageflow/widget.rb +4 -3
  186. data/app/models/pageflow/with_file_usage_extension.rb +1 -1
  187. data/app/models/pageflow/zencoder_attachment.rb +8 -8
  188. data/app/policies/pageflow/account_policy.rb +3 -1
  189. data/app/policies/pageflow/admin/admin_only_tab_policy.rb +1 -0
  190. data/app/policies/pageflow/admin/entry_tab_policy.rb +1 -0
  191. data/app/policies/pageflow/application_policy.rb +2 -0
  192. data/app/policies/pageflow/entry_policy.rb +7 -1
  193. data/app/policies/pageflow/entry_template_policy.rb +2 -1
  194. data/app/policies/pageflow/file_policy.rb +4 -7
  195. data/app/policies/pageflow/folder_policy.rb +18 -8
  196. data/app/policies/pageflow/membership_policy.rb +6 -4
  197. data/app/policies/pageflow/site_policy.rb +10 -3
  198. data/app/policies/pageflow/user_policy.rb +6 -4
  199. data/app/state_machines/pageflow/image_and_text_track_processing_state_machine.rb +3 -2
  200. data/app/state_machines/pageflow/media_encoding_state_machine.rb +5 -4
  201. data/app/views/admin/accounts/_entry_template_details.html.arb +2 -2
  202. data/app/views/admin/entries/_attributes_table.html.arb +6 -5
  203. data/app/views/admin/entries/_form.html.erb +2 -1
  204. data/app/views/admin/entries/_permalink_inputs.html.erb +9 -2
  205. data/app/views/admin/entry_templates/_form.html.erb +1 -3
  206. data/app/views/admin/site_root_entry/choose.html.erb +19 -0
  207. data/app/views/admin/sites/_fields.html.erb +14 -1
  208. data/app/views/admin/translations/_form.html.erb +31 -0
  209. data/app/views/admin/users/_attributes_table.html.arb +13 -0
  210. data/app/views/components/pageflow/admin/add_membership_button.rb +13 -12
  211. data/app/views/components/pageflow/admin/custom_scopes_renderer.rb +1 -0
  212. data/app/views/components/pageflow/admin/embed_code_field.rb +1 -0
  213. data/app/views/components/pageflow/admin/embedded_index_table.rb +9 -10
  214. data/app/views/components/pageflow/admin/entries_tab.rb +1 -0
  215. data/app/views/components/pageflow/admin/entry_publication_state_indicator.rb +6 -5
  216. data/app/views/components/pageflow/admin/entry_templates_tab.rb +2 -1
  217. data/app/views/components/pageflow/admin/entry_translations_tab.rb +102 -0
  218. data/app/views/components/pageflow/admin/entry_user_badge_list.rb +1 -0
  219. data/app/views/components/pageflow/admin/extensible_attributes_table.rb +9 -8
  220. data/app/views/components/pageflow/admin/features_tab.rb +1 -0
  221. data/app/views/components/pageflow/admin/grouped_folder_list.rb +1 -0
  222. data/app/views/components/pageflow/admin/icon_link_to.rb +1 -0
  223. data/app/views/components/pageflow/admin/members_tab.rb +4 -3
  224. data/app/views/components/pageflow/admin/membership_role_with_tooltip.rb +3 -2
  225. data/app/views/components/pageflow/admin/revisions_tab.rb +14 -10
  226. data/app/views/components/pageflow/admin/sites_tab.rb +1 -0
  227. data/app/views/components/pageflow/admin/tabs_view.rb +1 -0
  228. data/app/views/components/pageflow/admin/timestamp.rb +6 -5
  229. data/app/views/components/pageflow/admin/user_account_badge_list.rb +2 -3
  230. data/app/views/components/pageflow/admin/user_accounts_tab.rb +1 -0
  231. data/app/views/components/pageflow/admin/user_entries_tab.rb +1 -0
  232. data/app/views/components/pageflow/admin/users_tab.rb +1 -0
  233. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +1 -1
  234. data/app/views/pageflow/editor/entries/index.json.jbuilder +1 -1
  235. data/app/views/pageflow/editor/entries/show.json.jbuilder +1 -1
  236. data/app/views/pageflow/editor/entry_publications/check.json.jbuilder +2 -2
  237. data/app/views/pageflow/editor/files/_file.json.jbuilder +5 -13
  238. data/app/views/pageflow/editor/files/create.json.jbuilder +1 -1
  239. data/app/views/pageflow/editor/files/index.json.jbuilder +1 -1
  240. data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
  241. data/app/views/pageflow/editor/video_files/_video_file.json.jbuilder +1 -3
  242. data/app/views/pageflow/entries/share_menu/_bluesky_link.html.erb +8 -0
  243. data/app/views/pageflow/entries/share_menu/_threads_link.html.erb +8 -0
  244. data/app/views/pageflow/files/_file.json.jbuilder +3 -3
  245. data/app/views/pageflow/sitemaps/index.xml.builder +9 -1
  246. data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
  247. data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
  248. data/config/initializers/active_admin_patches.rb +3 -6
  249. data/config/initializers/admin_resource_tabs.rb +3 -0
  250. data/config/initializers/paperclip.rb +1 -0
  251. data/config/initializers/symmetric_encryption.rb +1 -1
  252. data/config/initializers/zencoder.rb +24 -13
  253. data/config/locales/de.yml +110 -4
  254. data/config/locales/en.yml +109 -7
  255. data/config/routes.rb +15 -13
  256. data/config/spring.rb +2 -1
  257. data/db/migrate/20140418225525_setup_schema.rb +2 -2
  258. data/db/migrate/20190306161431_copy_file_attributes_of_failed_uploads.rb +2 -2
  259. data/db/migrate/20190820152900_drop_accounts_themes.rb +2 -1
  260. data/db/migrate/20191202145757_create_pageflow_scrolled_sections.rb +11 -11
  261. data/db/migrate/20191202150657_create_pageflow_scrolled_chapters.rb +1 -1
  262. data/db/migrate/20191202154723_create_pageflow_scrolled_content_elements.rb +9 -9
  263. data/db/migrate/20191219143450_add_position_to_content_elements.rb +2 -1
  264. data/db/migrate/20200117133200_change_revision_appearance_option_default_and_null.rb +2 -1
  265. data/db/migrate/20200122115400_create_pageflow_entry_templates.rb +25 -25
  266. data/db/migrate/20200206134400_convert_legacy_scrolled_content_element_types.rb +3 -3
  267. data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +2 -2
  268. data/db/migrate/20230120092923_create_other_files.rb +2 -1
  269. data/db/migrate/20230419083307_create_pageflow_entry_translation_group.rb +9 -0
  270. data/db/migrate/20240612110434_add_cutoff_mode_name_to_sites.rb +5 -0
  271. data/db/migrate/20240918084059_create_pageflow_permalink_redirects.rb +14 -0
  272. data/db/migrate/20250508172234_ensure_scrolled_entries_have_main_storyline.rb +14 -0
  273. data/db/migrate/20250617090048_add_custom404_entry_to_sites.rb +5 -0
  274. data/db/migrate/20250617100000_add_perma_id_counter_to_entries.rb +28 -0
  275. data/db/migrate/20250722174123_add_perma_id_to_chapters.rb +10 -0
  276. data/db/migrate/20250725080603_add_perma_id_indexes_to_revision_components.rb +13 -0
  277. data/db/migrate/20250726000000_add_display_name_to_file_usages.rb +5 -0
  278. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +3912 -1486
  279. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +468 -1161
  280. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +28125 -22
  281. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +26589 -19
  282. data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +1 -0
  283. data/entry_types/paged/app/helpers/pageflow_paged/page_background_asset_helper.rb +1 -1
  284. data/entry_types/paged/app/helpers/pageflow_paged/third_party_embed_consent_helper.rb +7 -7
  285. data/entry_types/paged/app/views/pageflow_paged/editor/entries/_seed.json.jbuilder +1 -0
  286. data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
  287. data/entry_types/paged/lib/pageflow_paged/plugin.rb +4 -0
  288. data/entry_types/paged/lib/pageflow_paged/react/page_type.rb +1 -1
  289. data/entry_types/paged/lib/pageflow_paged/react/widget_type.rb +3 -3
  290. data/entry_types/paged/lib/pageflow_paged.rb +1 -1
  291. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +5 -3
  292. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +2 -2
  293. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -2
  294. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +2 -1
  295. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +2 -2
  296. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +1 -0
  297. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +2 -1
  298. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +60 -6
  299. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +16 -2
  300. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +21 -23
  301. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +16 -1
  302. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +15 -14
  303. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +12 -0
  304. data/entry_types/scrolled/app/models/pageflow_scrolled/section.rb +12 -1
  305. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +19 -1
  306. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -0
  307. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +2 -2
  308. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +2 -0
  309. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +17 -9
  310. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry_translations.json.jbuilder +14 -0
  311. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +25 -5
  312. data/entry_types/scrolled/app/views/pageflow_scrolled/storylines/_storyline.json.jbuilder +7 -0
  313. data/entry_types/scrolled/config/locales/de.yml +614 -45
  314. data/entry_types/scrolled/config/locales/en.yml +586 -47
  315. data/entry_types/scrolled/config/routes.rb +18 -8
  316. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +11 -11
  317. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantDesktop.svg +56 -0
  318. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDarkVariantMobile.svg +22 -0
  319. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/themes_plugin.rb.tt +26 -11
  320. data/entry_types/scrolled/lib/pageflow_scrolled/additional_packs.rb +27 -8
  321. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +1 -1
  322. data/entry_types/scrolled/lib/pageflow_scrolled/additional_theme_assets.rb +27 -0
  323. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +16 -4
  324. data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +1 -1
  325. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +24 -4
  326. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +24 -22
  327. data/entry_types/scrolled/lib/pageflow_scrolled.rb +1 -1
  328. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +6 -5
  329. data/entry_types/scrolled/package/config/webpack.js +22 -0
  330. data/entry_types/scrolled/package/contentElements/hotspots-frontend.css +1 -0
  331. data/entry_types/scrolled/package/contentElements/hotspots-frontend.js +1529 -0
  332. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.css +1 -0
  333. data/entry_types/scrolled/package/contentElements/tikTokEmbed-frontend.js +59 -0
  334. data/entry_types/scrolled/package/contentElements-editor.js +2075 -321
  335. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  336. data/entry_types/scrolled/package/contentElements-frontend.js +1019 -643
  337. data/entry_types/scrolled/package/editor.js +2086 -1091
  338. data/entry_types/scrolled/package/frontend/{EditableInlineText.module-ebd22921.js → FloatingPortalRootProvider-51914be7.js} +1200 -1258
  339. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-4ec6b2de.js → PhonePlatformContext-9f76033e.js} +7 -8
  340. data/entry_types/scrolled/package/frontend/ThemeIcon-81f2f066.js +1932 -0
  341. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-788e9cdb.js +39 -0
  342. data/entry_types/scrolled/package/frontend/{Viewer-1bb5597c.js → Viewer-0345ce57.js} +36 -63
  343. data/entry_types/scrolled/package/frontend/{Viewer-1ecf3375.js → Viewer-cdc549cc.js} +15 -22
  344. data/entry_types/scrolled/package/frontend/{Wavesurfer-7d9cf1b7.js → Wavesurfer-1cdc3925.js} +54 -74
  345. data/entry_types/scrolled/package/frontend/{components-024a9893.js → components-96660ffd.js} +1791 -841
  346. data/entry_types/scrolled/package/frontend/{index-11f32f10.js → index-eb670c2f.js} +11 -18
  347. data/entry_types/scrolled/package/frontend/index.css +1 -1
  348. data/entry_types/scrolled/package/frontend/index.js +517 -903
  349. data/entry_types/scrolled/package/frontend/{createSuper-d0f30da3.js → inherits-539844a6.js} +40 -56
  350. data/entry_types/scrolled/package/frontend/{useContentElementEditorState-4f4c3cf6.js → useContentElementEditorState-77fe6c79.js} +7 -8
  351. data/entry_types/scrolled/package/frontend/usePhonePlatform-c2ba875d.js +8 -0
  352. data/entry_types/scrolled/package/frontend-server.js +0 -1
  353. data/entry_types/scrolled/package/package.json +18 -10
  354. data/entry_types/scrolled/package/testHelpers.js +306 -70
  355. data/entry_types/scrolled/package/values/widgets.module.css +18 -0
  356. data/entry_types/scrolled/package/widgets/consentBar.css +1 -1
  357. data/entry_types/scrolled/package/widgets/consentBar.js +47 -66
  358. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  359. data/entry_types/scrolled/package/widgets/defaultNavigation.js +177 -207
  360. data/entry_types/scrolled/package/widgets/excursionDialog.css +1 -0
  361. data/entry_types/scrolled/package/widgets/excursionDialog.js +109 -0
  362. data/entry_types/scrolled/package/widgets/excursionSheet.css +1 -0
  363. data/entry_types/scrolled/package/widgets/excursionSheet.js +262 -0
  364. data/entry_types/scrolled/package/widgets/iconInlineFileRights.css +1 -1
  365. data/entry_types/scrolled/package/widgets/iconInlineFileRights.js +6 -9
  366. data/entry_types/scrolled/package/widgets/iconScrollIndicator.css +1 -0
  367. data/entry_types/scrolled/package/widgets/iconScrollIndicator.js +48 -0
  368. data/entry_types/scrolled/package/widgets/mainStorylineSheet.css +1 -0
  369. data/entry_types/scrolled/package/widgets/mainStorylineSheet.js +144 -0
  370. data/entry_types/scrolled/package/widgets/textInlineFileRights.css +1 -1
  371. data/entry_types/scrolled/package/widgets/textInlineFileRights.js +26 -9
  372. data/entry_types/scrolled/package/widgets-server.js +1 -0
  373. data/entry_types/scrolled/spec/factories/chapters.rb +14 -1
  374. data/entry_types/scrolled/spec/factories/content_elements.rb +1 -1
  375. data/lib/generators/pageflow/active_admin_initializer/active_admin_initializer_generator.rb +5 -3
  376. data/lib/generators/pageflow/assets/assets_generator.rb +7 -5
  377. data/lib/generators/pageflow/cancan/cancan_generator.rb +2 -1
  378. data/lib/generators/pageflow/cancan/templates/ability.rb +1 -1
  379. data/lib/generators/pageflow/error_pages/error_pages_generator.rb +2 -1
  380. data/lib/generators/pageflow/initializer/initializer_generator.rb +3 -2
  381. data/lib/generators/pageflow/install/install_generator.rb +2 -2
  382. data/lib/generators/pageflow/procfile/procfile_generator.rb +2 -1
  383. data/lib/generators/pageflow/resque/resque_generator.rb +6 -4
  384. data/lib/generators/pageflow/resque/templates/resque.rake +1 -1
  385. data/lib/generators/pageflow/routes/routes_generator.rb +4 -2
  386. data/lib/generators/pageflow/seeds/seeds_generator.rb +3 -2
  387. data/lib/generators/pageflow/seeds/templates/seeds.rb +6 -6
  388. data/lib/generators/pageflow/theme/theme_generator.rb +2 -1
  389. data/lib/generators/pageflow/user/user_generator.rb +2 -1
  390. data/lib/pageflow/ability_mixin.rb +25 -15
  391. data/lib/pageflow/active_admin_patches/views/attributes_table.rb +1 -0
  392. data/lib/pageflow/active_admin_patches/views/pages/base.rb +3 -2
  393. data/lib/pageflow/active_admin_patches/views/table_for.rb +1 -0
  394. data/lib/pageflow/additional_headers.rb +27 -0
  395. data/lib/pageflow/admin/attributes_table_rows.rb +3 -3
  396. data/lib/pageflow/admin/tabs.rb +1 -1
  397. data/lib/pageflow/built_in_file_type.rb +1 -1
  398. data/lib/pageflow/built_in_page_types_plugin.rb +1 -1
  399. data/lib/pageflow/built_in_widget_type.rb +2 -2
  400. data/lib/pageflow/built_in_widget_types_plugin.rb +2 -1
  401. data/lib/pageflow/configuration.rb +141 -18
  402. data/lib/pageflow/cutoff_modes.rb +39 -0
  403. data/lib/pageflow/editor_controller.rb +6 -10
  404. data/lib/pageflow/engine.rb +4 -5
  405. data/lib/pageflow/entry_export_import/attachment_files.rb +1 -1
  406. data/lib/pageflow/entry_export_import/entry_serialization.rb +5 -4
  407. data/lib/pageflow/entry_export_import/file_mappings.rb +1 -0
  408. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +1 -1
  409. data/lib/pageflow/entry_export_import.rb +3 -3
  410. data/lib/pageflow/entry_types.rb +2 -2
  411. data/lib/pageflow/feature.rb +1 -1
  412. data/lib/pageflow/features.rb +4 -6
  413. data/lib/pageflow/file_importers.rb +4 -4
  414. data/lib/pageflow/file_type.rb +3 -3
  415. data/lib/pageflow/file_types.rb +3 -3
  416. data/lib/pageflow/global_config_api.rb +5 -6
  417. data/lib/pageflow/help_entries.rb +7 -7
  418. data/lib/pageflow/help_entry.rb +1 -1
  419. data/lib/pageflow/hooks.rb +1 -1
  420. data/lib/pageflow/nested_revision_component.rb +9 -27
  421. data/lib/pageflow/news_item_api.rb +1 -1
  422. data/lib/pageflow/page_type.rb +2 -3
  423. data/lib/pageflow/page_types.rb +3 -3
  424. data/lib/pageflow/paperclip_interpolations/support.rb +1 -1
  425. data/lib/pageflow/paperclip_processors/vtt.rb +1 -0
  426. data/lib/pageflow/paperclip_processors/webp.rb +2 -2
  427. data/lib/pageflow/partial_editor_fragment_renderer.rb +2 -2
  428. data/lib/pageflow/plugin.rb +1 -2
  429. data/lib/pageflow/quota.rb +9 -5
  430. data/lib/pageflow/quotas.rb +1 -1
  431. data/lib/pageflow/rails_version.rb +1 -0
  432. data/lib/pageflow/react.rb +1 -1
  433. data/lib/pageflow/revision_component.rb +8 -40
  434. data/lib/pageflow/revision_components.rb +16 -6
  435. data/lib/pageflow/seeds.rb +12 -16
  436. data/lib/pageflow/theme.rb +1 -1
  437. data/lib/pageflow/theme_customizations.rb +10 -10
  438. data/lib/pageflow/themes.rb +3 -3
  439. data/lib/pageflow/user_mixin.rb +6 -6
  440. data/lib/pageflow/version.rb +1 -1
  441. data/lib/pageflow/widget_type.rb +4 -4
  442. data/lib/pageflow/widget_types.rb +9 -9
  443. data/lib/pageflow/zencoder_api.rb +32 -42
  444. data/lib/pageflow/zencoder_audio_output_definition.rb +14 -13
  445. data/lib/pageflow/zencoder_meta_data_output_definition.rb +3 -2
  446. data/lib/pageflow/zencoder_output_definition.rb +16 -14
  447. data/lib/pageflow/zencoder_video_output_definition.rb +140 -88
  448. data/lib/pageflow.rb +7 -2
  449. data/lib/tasks/pageflow_tasks.rake +1 -1
  450. data/package/editor.js +954 -868
  451. data/package/frontend.js +113 -387
  452. data/package/package.json +2 -1
  453. data/package/testHelpers.js +10 -56
  454. data/package/ui.js +209 -251
  455. data/spec/factories/accounts.rb +37 -22
  456. data/spec/factories/audio_files.rb +2 -2
  457. data/spec/factories/authentication_tokens.rb +4 -4
  458. data/spec/factories/chapters.rb +4 -4
  459. data/spec/factories/draft_entries.rb +14 -6
  460. data/spec/factories/edit_locks.rb +1 -1
  461. data/spec/factories/entries.rb +28 -19
  462. data/spec/factories/entry_translation_groups.rb +6 -0
  463. data/spec/factories/file_usages.rb +2 -1
  464. data/spec/factories/folders.rb +1 -1
  465. data/spec/factories/image_files.rb +2 -2
  466. data/spec/factories/pages.rb +3 -3
  467. data/spec/factories/published_entries.rb +26 -8
  468. data/spec/factories/revisions.rb +1 -1
  469. data/spec/factories/sites.rb +6 -0
  470. data/spec/factories/test_multi_attachment_files.rb +1 -1
  471. data/spec/factories/text_track_files.rb +1 -1
  472. data/spec/factories/uploadable_files.rb +1 -1
  473. data/spec/factories/users.rb +6 -6
  474. data/spec/factories/video_files.rb +2 -2
  475. data/spec/factories/widgets.rb +1 -1
  476. data/spec/fixtures/7x15_rotated.jpg +0 -0
  477. data/vendor/assets/javascripts/wysihtml-toolbar.js +19288 -0
  478. metadata +98 -45
  479. data/config/initializers/revision_components.rb +0 -5
  480. data/config/locales/twitter_to_x.de.yml +0 -6
  481. data/config/locales/twitter_to_x.en.yml +0 -6
  482. data/entry_types/scrolled/config/locales/twitter_to_x.de.yml +0 -12
  483. data/entry_types/scrolled/config/locales/twitter_to_x.en.yml +0 -12
  484. data/entry_types/scrolled/config/locales/vr_image_projection.de.yml +0 -24
  485. data/entry_types/scrolled/config/locales/vr_image_projection.en.yml +0 -24
  486. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-b79159cc.js +0 -107
  487. data/entry_types/scrolled/package/frontend/arrowRight-62998af9.js +0 -77
  488. data/entry_types/scrolled/package/frontend/i18n-ce13a8bf.js +0 -1129
data/package/ui.js CHANGED
@@ -3,6 +3,7 @@ import _ from 'underscore';
3
3
  import $ from 'jquery';
4
4
  import I18n$1 from 'i18n-js';
5
5
  import Backbone from 'backbone';
6
+ import Sortable from 'sortablejs';
6
7
  import ChildViewContainer from 'backbone.babysitter';
7
8
  import IScroll from 'iscroll';
8
9
  import 'jquery.minicolors';
@@ -16,15 +17,12 @@ Marionette.Renderer.render = function (template, data) {
16
17
  if (_.isFunction(template)) {
17
18
  return template(data);
18
19
  }
19
-
20
20
  if (template.indexOf('templates/') === 0) {
21
21
  template = 'pageflow/editor/' + template;
22
22
  }
23
-
24
23
  if (!JST[template]) {
25
24
  throw "Template '" + template + "' not found!";
26
25
  }
27
-
28
26
  return JST[template](data);
29
27
  };
30
28
 
@@ -50,22 +48,19 @@ Marionette.Renderer.render = function (template, data) {
50
48
  * @memberof i18nUtils
51
49
  * @since 12.0
52
50
  */
53
-
54
51
  function attributeTranslationKeys(attributeName, keyName, options) {
55
52
  var result = [];
56
-
57
53
  if (options.prefixes) {
58
54
  result = result.concat(_(options.prefixes).map(function (prefix) {
59
55
  return prefix + '.' + attributeName + '.' + keyName;
60
56
  }, this));
61
57
  }
62
-
63
58
  if (options && options.fallbackPrefix) {
64
59
  result.push(options.fallbackPrefix + '.' + options.fallbackModelI18nKey + '.' + attributeName);
65
60
  }
66
-
67
61
  return result;
68
62
  }
63
+
69
64
  /**
70
65
  * Takes the same parameters as {@link
71
66
  * #i18nutilsattributetranslationkeys attributeTranslationKeys}, but returns the first existing
@@ -75,10 +70,10 @@ function attributeTranslationKeys(attributeName, keyName, options) {
75
70
  * @memberof i18nUtils
76
71
  * @since 12.0
77
72
  */
78
-
79
73
  function attributeTranslation(attributeName, keyName, options) {
80
74
  return findTranslation(attributeTranslationKeys(attributeName, keyName, options));
81
75
  }
76
+
82
77
  /**
83
78
  * Find the first key for which a translation exists and return the
84
79
  * translation.
@@ -97,19 +92,15 @@ function attributeTranslation(attributeName, keyName, options) {
97
92
  * @memberof i18nUtils
98
93
  * @return {string}
99
94
  */
100
-
101
95
  function findTranslation(keys, options) {
102
96
  options = options || {};
103
-
104
97
  if (options.html) {
105
98
  keys = translationKeysWithSuffix(keys, 'html');
106
99
  }
107
-
108
100
  return _.chain(keys).reverse().reduce(function (result, key) {
109
101
  var unescapedTranslation = I18n$1.t(key, _.extend({}, options, {
110
102
  defaultValue: result
111
103
  }));
112
-
113
104
  if (!options.html || key.match(/_html$/) || result == unescapedTranslation) {
114
105
  return unescapedTranslation;
115
106
  } else {
@@ -117,6 +108,7 @@ function findTranslation(keys, options) {
117
108
  }
118
109
  }, options.defaultValue).value();
119
110
  }
111
+
120
112
  /**
121
113
  * Return the first key for which a translation exists. Returns the
122
114
  * first if non of the keys has a translation.
@@ -127,7 +119,6 @@ function findTranslation(keys, options) {
127
119
  * @memberof i18nUtils
128
120
  * @return {string}
129
121
  */
130
-
131
122
  function findKeyWithTranslation(keys) {
132
123
  var missing = '_not_translated';
133
124
  return _(keys).detect(function (key) {
@@ -252,12 +243,12 @@ function ui(styles) {
252
243
  for (var _len = arguments.length, classNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
253
244
  classNames[_key - 1] = arguments[_key];
254
245
  }
255
-
256
246
  return classNames.reduce(function (result, className) {
257
247
  result[className] = selector(styles, className);
258
248
  return result;
259
249
  }, {});
260
250
  }
251
+
261
252
  /**
262
253
  * Create object that can be passed to Marionette events property from CSS
263
254
  * module object.
@@ -295,18 +286,17 @@ function ui(styles) {
295
286
  *
296
287
  * @memberof cssModulesUtils
297
288
  */
298
-
299
289
  function events(styles, mapping) {
300
290
  return Object.keys(mapping).reduce(function (result, key) {
301
291
  var _key$split = key.split(' '),
302
- _key$split2 = _slicedToArray(_key$split, 2),
303
- event = _key$split2[0],
304
- className = _key$split2[1];
305
-
292
+ _key$split2 = _slicedToArray(_key$split, 2),
293
+ event = _key$split2[0],
294
+ className = _key$split2[1];
306
295
  result["".concat(event, " ").concat(selector(styles, className))] = mapping[key];
307
296
  return result;
308
297
  }, {});
309
298
  }
299
+
310
300
  /**
311
301
  * Generates a CSS selector from a CSS module rule.
312
302
  *
@@ -319,14 +309,11 @@ function events(styles, mapping) {
319
309
  * @return {String} CSS Selector
320
310
  * @memberof cssModulesUtils
321
311
  */
322
-
323
312
  function selector(styles, className) {
324
313
  var classNames = styles[className];
325
-
326
314
  if (!classNames) {
327
315
  throw new Error("Unknown class name ".concat(className, " in mapping. Knwon names: ").concat(Object.keys(styles).join(', '), "."));
328
316
  }
329
-
330
317
  return ".".concat(classNames.replace(/ /g, '.'));
331
318
  }
332
319
 
@@ -337,28 +324,26 @@ var cssModulesUtils = /*#__PURE__*/Object.freeze({
337
324
  selector: selector
338
325
  });
339
326
 
327
+ // Class-y constructor by github.com/opensas
340
328
  // https://github.com/jashkenas/backbone/issues/2601
341
329
 
342
330
  function BaseObject(options) {
343
331
  this.initialize.apply(this, arguments);
344
332
  }
345
-
346
333
  _.extend(BaseObject.prototype, Backbone.Events, {
347
334
  initialize: function initialize(options) {}
348
- }); // The self-propagating extend function that Backbone classes use.
349
-
335
+ });
350
336
 
337
+ // The self-propagating extend function that Backbone classes use.
351
338
  BaseObject.extend = Backbone.Model.extend;
352
339
 
353
340
  var serverSideValidation = {
354
341
  initialize: function initialize() {
355
342
  var _this = this;
356
-
357
343
  this.validationErrors = {};
358
344
  this.listenTo(this, 'error', function (model, request) {
359
345
  if (request.status === 422) {
360
346
  _this.validationErrors = JSON.parse(request.responseText).errors;
361
-
362
347
  _this.trigger('invalid');
363
348
  }
364
349
  });
@@ -376,7 +361,6 @@ var CollectionView = Marionette.View.extend({
376
361
  this.listenTo(this.collection, 'add', this.addItem);
377
362
  this.listenTo(this.collection, 'remove', this.removeItem);
378
363
  this.listenTo(this.collection, 'sort', this.sort);
379
-
380
364
  if (this.options.loadingViewConstructor) {
381
365
  this.listenTo(this.collection, 'request', function () {
382
366
  this.loading = true;
@@ -397,7 +381,6 @@ var CollectionView = Marionette.View.extend({
397
381
  this.togglePlaceHolder();
398
382
  this.rendered = true;
399
383
  }
400
-
401
384
  return this;
402
385
  },
403
386
  onClose: function onClose() {
@@ -409,24 +392,20 @@ var CollectionView = Marionette.View.extend({
409
392
  model: item
410
393
  }, this.getItemViewOptions(item)));
411
394
  this.itemViews.add(view);
412
-
413
395
  if (this.rendered) {
414
396
  var index = this.collection.indexOf(item);
415
397
  view.render();
416
398
  view.$el.data('view', view);
417
-
418
399
  if (index > 0) {
419
400
  this.$el.children().eq(index - 1).after(view.el);
420
401
  } else {
421
402
  this.$el.prepend(view.el);
422
403
  }
423
-
424
404
  this.togglePlaceHolder();
425
405
  }
426
406
  },
427
407
  removeItem: function removeItem(item) {
428
408
  var view = this.itemViews.findByModel(item);
429
-
430
409
  if (view) {
431
410
  this.itemViews.remove(view);
432
411
  view.close();
@@ -438,19 +417,15 @@ var CollectionView = Marionette.View.extend({
438
417
  this.collection.each(function (item) {
439
418
  var itemView = this.itemViews.findByModel(item);
440
419
  var element;
441
-
442
420
  if (!itemView) {
443
421
  return;
444
422
  }
445
-
446
423
  element = itemView.$el;
447
-
448
424
  if (last) {
449
425
  last.after(element);
450
426
  } else {
451
427
  this.$el.prepend(element);
452
428
  }
453
-
454
429
  last = element;
455
430
  }, this);
456
431
  },
@@ -470,7 +445,6 @@ var CollectionView = Marionette.View.extend({
470
445
  togglePlaceHolder: function togglePlaceHolder() {
471
446
  var lastPlaceholderConstructor = this.placeHolderConstructor;
472
447
  this.placeHolderConstructor = this.getPlaceHolderConstructor();
473
-
474
448
  if (this.itemViews.length || !this.placeHolderConstructor) {
475
449
  this.closePlaceHolderView();
476
450
  } else if (!this.placeHolderView || lastPlaceholderConstructor !== this.placeHolderConstructor) {
@@ -490,31 +464,47 @@ var CollectionView = Marionette.View.extend({
490
464
 
491
465
  var SortableCollectionView = CollectionView.extend({
492
466
  render: function render() {
467
+ var _this = this;
493
468
  CollectionView.prototype.render.call(this);
494
- this.$el.sortable({
495
- connectWith: this.options.connectWith,
496
- placeholder: 'sortable-placeholder',
497
- forcePlaceholderSize: true,
498
- delay: 200,
499
- update: _.bind(function (event, ui) {
500
- if (ui.item.parent().is(this.el)) {
501
- this.updateOrder();
469
+ this.sortable = Sortable.create(this.el, {
470
+ group: this.options.connectWith,
471
+ animation: 150,
472
+ ghostClass: 'sortable-placeholder',
473
+ forceFallback: this.options.forceDraggableFallback,
474
+ fallbackTolerance: 3,
475
+ onEnd: function onEnd(event) {
476
+ var item = $(event.item);
477
+ if (item.parent().is(_this.el)) {
478
+ _this.updateOrder();
502
479
  }
503
- }, this),
504
- receive: _.bind(function (event, ui) {
505
- var view = ui.item.data('view');
506
- this.reindexPositions();
507
- this.itemViews.add(view);
508
- this.collection.add(view.model);
509
- }, this),
510
- remove: _.bind(function (event, ui) {
511
- var view = ui.item.data('view');
512
- this.itemViews.remove(view);
513
- this.collection.remove(view.model);
514
- }, this)
480
+ },
481
+ onRemove: function onRemove(event) {
482
+ var view = $(event.item).data('view');
483
+ _this.itemViews.remove(view);
484
+ _this.collection.remove(view.model);
485
+ },
486
+ onSort: function onSort(event) {
487
+ if (event.from !== event.to && event.to === _this.el) {
488
+ var view = $(event.item).data('view');
489
+ _this.reindexPositions();
490
+ _this.itemViews.add(view);
491
+ _this.collection.add(view.model);
492
+ _this.collection.saveOrder();
493
+ }
494
+ }
515
495
  });
516
496
  return this;
517
497
  },
498
+ onClose: function onClose() {
499
+ CollectionView.prototype.onClose.call(this);
500
+ this.sortable.destroy();
501
+ },
502
+ disableSorting: function disableSorting() {
503
+ this.sortable.option('disabled', true);
504
+ },
505
+ enableSorting: function enableSorting() {
506
+ this.sortable.option('disabled', false);
507
+ },
518
508
  addItem: function addItem(item) {
519
509
  if (!this.itemViews.findByModel(item)) {
520
510
  CollectionView.prototype.addItem.call(this, item);
@@ -537,6 +527,41 @@ var SortableCollectionView = CollectionView.extend({
537
527
  }
538
528
  });
539
529
 
530
+ function _objectWithoutPropertiesLoose(source, excluded) {
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"];
540
565
  var ConfigurationEditorTabView = Marionette.View.extend({
541
566
  className: 'configuration_editor_tab',
542
567
  initialize: function initialize() {
@@ -571,27 +596,27 @@ var ConfigurationEditorTabView = Marionette.View.extend({
571
596
  }
572
597
  }
573
598
  });
574
-
575
599
  ConfigurationEditorTabView.Groups = function () {
576
600
  var groups = {};
577
-
578
601
  this.define = function (name, fn) {
579
602
  if (typeof fn !== 'function') {
580
603
  throw 'Group has to be function.';
581
604
  }
582
-
583
605
  groups[name] = fn;
584
606
  };
585
-
586
- this.apply = function (name, context, options) {
607
+ this.apply = function (name, context) {
608
+ var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
609
+ ignoreUndefined = _ref.ignoreUndefined,
610
+ options = _objectWithoutProperties(_ref, _excluded);
587
611
  if (!(name in groups)) {
612
+ if (ignoreUndefined) {
613
+ return;
614
+ }
588
615
  throw 'Undefined group named "' + name + '".';
589
616
  }
590
-
591
617
  groups[name].call(context, options || {});
592
618
  };
593
619
  };
594
-
595
620
  ConfigurationEditorTabView.groups = new ConfigurationEditorTabView.Groups();
596
621
 
597
622
  function template(data) {
@@ -601,6 +626,7 @@ return __p
601
626
  }
602
627
 
603
628
  /*global pageflow*/
629
+
604
630
  /**
605
631
  * Switch between different views using tabs.
606
632
  *
@@ -621,10 +647,7 @@ return __p
621
647
  *
622
648
  * @class
623
649
  */
624
-
625
- var TabsView = Marionette.Layout.extend(
626
- /* @lends TabView.prototype */
627
- {
650
+ var TabsView = Marionette.Layout.extend( /* @lends TabView.prototype */{
628
651
  template: template,
629
652
  className: 'tabs_view',
630
653
  ui: {
@@ -643,7 +666,6 @@ var TabsView = Marionette.Layout.extend(
643
666
  this.tabFactoryFns = {};
644
667
  this.tabNames = [];
645
668
  this.currentTabName = null;
646
-
647
669
  this._refreshScrollerOnSideBarResize();
648
670
  },
649
671
  tab: function tab(name, factoryFn) {
@@ -655,7 +677,6 @@ var TabsView = Marionette.Layout.extend(
655
677
  var label = findTranslation(this._labelTranslationKeys(name));
656
678
  this.ui.headers.append($('<li />').attr('data-tab-name', name).text(label));
657
679
  }, this);
658
-
659
680
  this.scroller = new IScroll(this.ui.scroller[0], {
660
681
  scrollX: true,
661
682
  scrollY: false,
@@ -667,9 +688,7 @@ var TabsView = Marionette.Layout.extend(
667
688
  },
668
689
  changeTab: function changeTab(name) {
669
690
  this.container.show(this.tabFactoryFns[name]());
670
-
671
691
  this._updateActiveHeader(name);
672
-
673
692
  this.currentTabName = name;
674
693
  },
675
694
  defaultTab: function defaultTab() {
@@ -679,14 +698,12 @@ var TabsView = Marionette.Layout.extend(
679
698
  return _.first(this.tabNames);
680
699
  }
681
700
  },
682
-
683
701
  /**
684
702
  * Rerender current tab.
685
703
  */
686
704
  refresh: function refresh() {
687
705
  this.changeTab(this.currentTabName);
688
706
  },
689
-
690
707
  /**
691
708
  * Adjust tabs scroller to changed width of view.
692
709
  */
@@ -700,15 +717,12 @@ var TabsView = Marionette.Layout.extend(
700
717
  var result = _.map(this.options.translationKeyPrefixes, function (prefix) {
701
718
  return prefix + '.' + name;
702
719
  });
703
-
704
720
  if (this.options.i18n) {
705
721
  result.push(this.options.i18n + '.' + name);
706
722
  }
707
-
708
723
  if (this.options.fallbackTranslationKeyPrefix) {
709
724
  result.push(this.options.fallbackTranslationKeyPrefix + '.' + name);
710
725
  }
711
-
712
726
  return result;
713
727
  },
714
728
  _updateActiveHeader: function _updateActiveHeader(activeTabName) {
@@ -756,7 +770,6 @@ var TabsView = Marionette.Layout.extend(
756
770
  *
757
771
  * @class
758
772
  */
759
-
760
773
  var ConfigurationEditorView = Marionette.View.extend({
761
774
  className: 'configuration_editor',
762
775
  initialize: function initialize() {
@@ -782,14 +795,12 @@ var ConfigurationEditorView = Marionette.View.extend({
782
795
  return tabView;
783
796
  }, this));
784
797
  },
785
-
786
798
  /**
787
799
  * Rerender current tab.
788
800
  */
789
801
  refresh: function refresh() {
790
802
  this.tabsView.refresh();
791
803
  },
792
-
793
804
  /**
794
805
  * Adjust tabs scroller to changed width of view.
795
806
  */
@@ -801,7 +812,6 @@ var ConfigurationEditorView = Marionette.View.extend({
801
812
  return this;
802
813
  }
803
814
  });
804
-
805
815
  _.extend(ConfigurationEditorView, {
806
816
  repository: {},
807
817
  register: function register(pageTypeName, prototype) {
@@ -829,7 +839,6 @@ return __p
829
839
  *
830
840
  * @since 12.0
831
841
  */
832
-
833
842
  var TableCellView = Marionette.ItemView.extend({
834
843
  tagName: 'td',
835
844
  template: template$1,
@@ -841,14 +850,12 @@ var TableCellView = Marionette.ItemView.extend({
841
850
  this.setupContentBinding();
842
851
  this.update();
843
852
  },
844
-
845
853
  /**
846
854
  * Override in concrete cell view.
847
855
  */
848
856
  update: function update() {
849
857
  throw 'Not implemented';
850
858
  },
851
-
852
859
  /**
853
860
  * Returns the column attribute's value in the row model.
854
861
  */
@@ -866,7 +873,6 @@ var TableCellView = Marionette.ItemView.extend({
866
873
  return this.model;
867
874
  }
868
875
  },
869
-
870
876
  /**
871
877
  * Look up attribute specific translations based on
872
878
  * `attributeTranslationKeyPrefixes` of the the parent `TableView`.
@@ -893,7 +899,6 @@ var TableCellView = Marionette.ItemView.extend({
893
899
  return prefix + '.' + this.options.column.name + '.' + keyName;
894
900
  }, this);
895
901
  },
896
-
897
902
  /**
898
903
  * Set up content binding to update this view upon change of
899
904
  * specified attribute on this.getModel().
@@ -942,7 +947,6 @@ var TableRowView = Marionette.View.extend({
942
947
  attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
943
948
  }, column.cellViewOptions || {})));
944
949
  }, this);
945
-
946
950
  this.updateClassName();
947
951
  return this;
948
952
  },
@@ -983,14 +987,12 @@ var TableView = Marionette.ItemView.extend({
983
987
  },
984
988
  onRender: function onRender() {
985
989
  var view = this;
986
-
987
990
  _(this.options.columns).each(function (column) {
988
991
  this.ui.headRow.append(this.subview(new TableHeaderCellView({
989
992
  column: column,
990
993
  attributeTranslationKeyPrefixes: this.options.attributeTranslationKeyPrefixes
991
994
  })).el);
992
995
  }, this);
993
-
994
996
  this.subview(new CollectionView({
995
997
  el: this.ui.body,
996
998
  collection: this.collection,
@@ -1044,7 +1046,6 @@ var TooltipView = Marionette.ItemView.extend({
1044
1046
  this.$el.toggleClass('align_bottom_right', options.align === 'bottom right');
1045
1047
  this.$el.toggleClass('align_bottom_left', options.align === 'bottom left');
1046
1048
  this.$el.toggleClass('align_top_center', options.align === 'top center');
1047
-
1048
1049
  if (options.align === 'bottom right' || options.align === 'bottom left') {
1049
1050
  offsetTop = 10;
1050
1051
  offsetLeft = 0;
@@ -1055,7 +1056,6 @@ var TooltipView = Marionette.ItemView.extend({
1055
1056
  offsetTop = -17;
1056
1057
  offsetLeft = 10;
1057
1058
  }
1058
-
1059
1059
  this.$el.css({
1060
1060
  top: position.top + offsetTop + 'px',
1061
1061
  left: position.left + offsetLeft + 'px'
@@ -1123,37 +1123,32 @@ var attributeBinding = {
1123
1123
  },
1124
1124
  setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
1125
1125
  var _this = this;
1126
-
1127
1126
  var normalize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (value) {
1128
1127
  return value;
1129
1128
  };
1130
1129
  var binding = this.options["".concat(optionName, "Binding")];
1130
+ var model = this.options["".concat(optionName, "BindingModel")] || this.model;
1131
1131
  var view = this;
1132
-
1133
1132
  if (binding) {
1134
1133
  _.flatten([binding]).forEach(function (attribute) {
1135
- _this.listenTo(_this.model, 'change:' + attribute, update);
1134
+ _this.listenTo(model, 'change:' + attribute, update);
1136
1135
  });
1137
1136
  }
1138
-
1139
1137
  update();
1140
-
1141
1138
  function update() {
1142
1139
  updateMethod.call(view, view.getAttributeBoundOption(optionName, normalize));
1143
1140
  }
1144
1141
  },
1145
1142
  getAttributeBoundOption: function getAttributeBoundOption(optionName) {
1146
- var _this2 = this;
1147
-
1148
1143
  var normalize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (value) {
1149
1144
  return value;
1150
1145
  };
1151
1146
  var binding = this.options["".concat(optionName, "Binding")];
1147
+ var model = this.options["".concat(optionName, "BindingModel")] || this.model;
1152
1148
  var bindingValueOptionName = "".concat(optionName, "BindingValue");
1153
1149
  var value = Array.isArray(binding) ? binding.map(function (attribute) {
1154
- return _this2.model.get(attribute);
1155
- }) : this.model.get(binding);
1156
-
1150
+ return model.get(attribute);
1151
+ }) : model.get(binding);
1157
1152
  if (bindingValueOptionName in this.options) {
1158
1153
  return value === this.options[bindingValueOptionName];
1159
1154
  } else if (typeof this.options[optionName] === 'function') {
@@ -1276,6 +1271,9 @@ var attributeBinding = {
1276
1271
  * Input will be disabled whenever the value of the `disabledBinding`
1277
1272
  * attribute equals the value of this option.
1278
1273
  *
1274
+ * @param {Backbone.Model} [options.disabledBindingModel]
1275
+ * Alternative model to bind to.
1276
+ *
1279
1277
  * @param {string|string[]} [options.visibleBinding]
1280
1278
  * Name of an attribute to control whether the input is visible. If
1281
1279
  * the `visible` and `visibleBindingValue` options are not set,
@@ -1292,16 +1290,17 @@ var attributeBinding = {
1292
1290
  * Input will be visible whenever the value of the `visibleBinding`
1293
1291
  * attribute equals the value of this option.
1294
1292
  *
1293
+ * @param {Backbone.Model} [options.visibleBindingModel]
1294
+ * Alternative model to bind to.
1295
+ *
1295
1296
  * @mixin
1296
1297
  */
1297
-
1298
1298
  var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1299
1299
  ui: {
1300
1300
  label: 'label',
1301
1301
  labelText: 'label .name',
1302
1302
  inlineHelp: 'label .inline_help'
1303
1303
  },
1304
-
1305
1304
  /**
1306
1305
  * Returns an array of translation keys based on the
1307
1306
  * `attributeTranslationKeyPrefixes` option and the given keyName.
@@ -1342,7 +1341,6 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1342
1341
  this.setupBooleanAttributeBinding('disabled', this.updateDisabled);
1343
1342
  this.setupBooleanAttributeBinding('visible', this.updateVisible);
1344
1343
  },
1345
-
1346
1344
  /**
1347
1345
  * The label to display in the form.
1348
1346
  * @return {string}
@@ -1357,12 +1355,10 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1357
1355
  },
1358
1356
  updateInlineHelp: function updateInlineHelp() {
1359
1357
  this.ui.inlineHelp.html(this.inlineHelpText());
1360
-
1361
1358
  if (!this.inlineHelpText()) {
1362
1359
  this.ui.inlineHelp.hide();
1363
1360
  }
1364
1361
  },
1365
-
1366
1362
  /**
1367
1363
  * The inline help text for the form field.
1368
1364
  * @return {string}
@@ -1371,11 +1367,9 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1371
1367
  var keys = this.attributeTranslationKeys('inline_help', {
1372
1368
  fallbackPrefix: 'pageflow.ui.inline_help'
1373
1369
  });
1374
-
1375
1370
  if (this.isDisabled()) {
1376
1371
  keys = translationKeysWithSuffix(keys, 'disabled');
1377
1372
  }
1378
-
1379
1373
  return _.compact([findTranslation(keys, {
1380
1374
  defaultValue: '',
1381
1375
  html: true
@@ -1394,7 +1388,6 @@ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1394
1388
  updateDisabled: function updateDisabled() {
1395
1389
  this.$el.toggleClass('input-disabled', !!this.isDisabled());
1396
1390
  this.updateInlineHelp();
1397
-
1398
1391
  if (this.ui.input) {
1399
1392
  this.updateDisabledAttribute(this.ui.input);
1400
1393
  }
@@ -1425,7 +1418,6 @@ return __p
1425
1418
  *
1426
1419
  * @class
1427
1420
  */
1428
-
1429
1421
  var CheckBoxGroupInputView = Marionette.ItemView.extend({
1430
1422
  mixins: [inputView],
1431
1423
  template: template$4,
@@ -1447,7 +1439,6 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
1447
1439
  return translationKeyPrefix + '.' + value;
1448
1440
  }, this);
1449
1441
  }
1450
-
1451
1442
  this.options.texts = _.map(this.options.translationKeys, function (key) {
1452
1443
  return I18n$1.t(key);
1453
1444
  });
@@ -1467,11 +1458,9 @@ var CheckBoxGroupInputView = Marionette.ItemView.extend({
1467
1458
  },
1468
1459
  save: function save() {
1469
1460
  var configured = {};
1470
-
1471
1461
  _.each(this.ui.container.find('input'), function (input) {
1472
1462
  configured[$(input).attr('name')] = $(input).prop('checked');
1473
1463
  });
1474
-
1475
1464
  this.model.set(this.options.propertyName, configured);
1476
1465
  },
1477
1466
  load: function load() {
@@ -1502,7 +1491,6 @@ return __p
1502
1491
  *
1503
1492
  * @class
1504
1493
  */
1505
-
1506
1494
  var UrlDisplayView = Marionette.ItemView.extend({
1507
1495
  mixins: [inputView],
1508
1496
  template: template$5,
@@ -1522,7 +1510,7 @@ var UrlDisplayView = Marionette.ItemView.extend({
1522
1510
  this.update();
1523
1511
  },
1524
1512
  update: function update() {
1525
- var url = this.model.get('original_url');
1513
+ var url = this.model.get(this.options.propertyName || 'original_url');
1526
1514
  this.$el.toggle(this.model.isUploaded() && !_.isEmpty(url));
1527
1515
  this.ui.link.attr('href', url);
1528
1516
  }
@@ -1562,7 +1550,6 @@ function _createClass(Constructor, protoProps, staticProps) {
1562
1550
  *
1563
1551
  * @class
1564
1552
  */
1565
-
1566
1553
  var NumberInputView = Marionette.ItemView.extend({
1567
1554
  mixins: [inputView],
1568
1555
  template: function template() {
@@ -1608,11 +1595,9 @@ var NumberInputView = Marionette.ItemView.extend({
1608
1595
  this.ui.input.attr('title', '');
1609
1596
  }
1610
1597
  });
1611
-
1612
1598
  var NumberParser = /*#__PURE__*/function () {
1613
1599
  function NumberParser(locale) {
1614
1600
  _classCallCheck(this, NumberParser);
1615
-
1616
1601
  var format = new Intl.NumberFormat(locale);
1617
1602
  var parts = format.formatToParts(12345.6);
1618
1603
  var numerals = Array.from({
@@ -1630,12 +1615,10 @@ var NumberParser = /*#__PURE__*/function () {
1630
1615
  return d.type === "decimal";
1631
1616
  }).value, "]"));
1632
1617
  this._numeral = new RegExp("[".concat(numerals.join(""), "]"), "g");
1633
-
1634
1618
  this._index = function (d) {
1635
1619
  return index.get(d);
1636
1620
  };
1637
1621
  }
1638
-
1639
1622
  _createClass(NumberParser, [{
1640
1623
  key: "parse",
1641
1624
  value: function parse(string) {
@@ -1643,7 +1626,6 @@ var NumberParser = /*#__PURE__*/function () {
1643
1626
  return string ? +string : NaN;
1644
1627
  }
1645
1628
  }]);
1646
-
1647
1629
  return NumberParser;
1648
1630
  }();
1649
1631
 
@@ -1671,7 +1653,6 @@ var NumberParser = /*#__PURE__*/function () {
1671
1653
  var inputWithPlaceholderText = {
1672
1654
  onRender: function onRender() {
1673
1655
  this.updatePlaceholder();
1674
-
1675
1656
  if (this.options.placeholderBinding) {
1676
1657
  this.listenTo(this.model, 'change:' + this.options.placeholderBinding, this.updatePlaceholder);
1677
1658
  }
@@ -1694,7 +1675,6 @@ var inputWithPlaceholderText = {
1694
1675
  return this.placeholderModelValue();
1695
1676
  }
1696
1677
  }
1697
-
1698
1678
  return '';
1699
1679
  },
1700
1680
  placeholderModelValue: function placeholderModelValue() {
@@ -1709,9 +1689,7 @@ var viewWithValidationErrorMessages = {
1709
1689
  },
1710
1690
  updateValidationErrorMessages: function updateValidationErrorMessages() {
1711
1691
  var _this = this;
1712
-
1713
1692
  var errors = this.model.validationErrors && this.model.validationErrors[this.options.propertyName] || [];
1714
-
1715
1693
  if (errors.length) {
1716
1694
  this.validationErrorList = this.validationErrorList || $('<ul class="validation_error_messages" />').appendTo(this.el);
1717
1695
  this.validationErrorList.html('');
@@ -1752,7 +1730,6 @@ return __p
1752
1730
  *
1753
1731
  * @class
1754
1732
  */
1755
-
1756
1733
  var TextInputView = Marionette.ItemView.extend({
1757
1734
  mixins: [inputView, inputWithPlaceholderText, viewWithValidationErrorMessages],
1758
1735
  template: template$6,
@@ -1782,21 +1759,20 @@ var TextInputView = Marionette.ItemView.extend({
1782
1759
  },
1783
1760
  load: function load() {
1784
1761
  var input = this.ui.input;
1785
- input.val(this.model.get(this.options.propertyName)); // set mysql varchar length as default for non-legacy data
1762
+ input.val(this.model.get(this.options.propertyName));
1786
1763
 
1787
- this.options.maxLength = this.options.maxLength || 255; // do not validate legacy data which length exceeds the specified maximum
1764
+ // set mysql varchar length as default for non-legacy data
1765
+ this.options.maxLength = this.options.maxLength || 255;
1766
+ // do not validate legacy data which length exceeds the specified maximum
1788
1767
  // for new and maxLength-conforming data: add validation
1789
-
1790
1768
  this.validateMaxLength = input.val().length <= this.options.maxLength;
1791
1769
  },
1792
1770
  validate: function validate() {
1793
1771
  var input = this.ui.input;
1794
-
1795
1772
  if (this.options.required && !input.val()) {
1796
1773
  this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.required_field'));
1797
1774
  return false;
1798
1775
  }
1799
-
1800
1776
  if (this.validateMaxLength && input.val().length > this.options.maxLength) {
1801
1777
  this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.text_input_view.max_characters_exceeded', {
1802
1778
  max_length: this.options.maxLength
@@ -1817,9 +1793,48 @@ var TextInputView = Marionette.ItemView.extend({
1817
1793
  }
1818
1794
  });
1819
1795
 
1796
+ function template$7(data) {
1797
+ var __p = '';
1798
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="file_name_input-wrapper">\n <input type="text" dir="auto" />\n <span class="file_name_input-extension"></span>\n</div>\n';
1799
+ return __p
1800
+ }
1801
+
1802
+ var FileNameInputView = TextInputView.extend({
1803
+ template: template$7,
1804
+ className: 'file_name_input',
1805
+ ui: Object.assign({}, TextInputView.prototype.ui, {
1806
+ extension: '.file_name_input-extension'
1807
+ }),
1808
+ onRender: function onRender() {
1809
+ TextInputView.prototype.onRender.call(this);
1810
+ },
1811
+ save: function save() {
1812
+ var baseName = this.ui.input.val();
1813
+ var extension = this.ui.extension.text();
1814
+ this.model.set(this.options.propertyName, baseName + extension);
1815
+ },
1816
+ load: function load() {
1817
+ var fullName = this.model.get(this.options.propertyName) || '';
1818
+ var match = fullName.match(/^(.*?)(\.[^.]+)?$/);
1819
+ var baseName = match ? match[1] : fullName;
1820
+ var extension = match && match[2] ? match[2] : '';
1821
+ this.ui.input.val(baseName);
1822
+ this.ui.extension.text(extension);
1823
+ this.options.maxLength = this.options.maxLength || 255;
1824
+ }
1825
+ });
1826
+
1827
+ function template$8(data) {
1828
+ var __p = '';
1829
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" dir="auto" autocomplete="off" />\n';
1830
+ return __p
1831
+ }
1832
+
1820
1833
  /**
1821
1834
  * Input view for a color value in hex representation.
1822
- * See {@link inputView} for further options
1835
+ *
1836
+ * See {@link inputWithPlaceholderText} for placeholder related
1837
+ * further options. See {@link inputView} for further options.
1823
1838
  *
1824
1839
  * @param {Object} [options]
1825
1840
  *
@@ -1835,6 +1850,14 @@ var TextInputView = Marionette.ItemView.extend({
1835
1850
  * defaultValue option is set, the value of the defaultValueBinding
1836
1851
  * attribute will be used as default value.
1837
1852
  *
1853
+ * @param {string|function} [options.placeholderColor]
1854
+ * Color to display in swatch by default.
1855
+ *
1856
+ * @param {string} [options.placeholderColorBinding]
1857
+ * Name of an attribute the placeholder color depends on. If a function
1858
+ * is used as placeholderColor option, it will be passed the value of the
1859
+ * placeholderColorBinding attribute each time it changes.
1860
+ *
1838
1861
  * @param {string[]} [options.swatches]
1839
1862
  * Preset color values to be displayed inside the picker drop
1840
1863
  * down. The default value, if present, is always used as the
@@ -1842,10 +1865,9 @@ var TextInputView = Marionette.ItemView.extend({
1842
1865
  *
1843
1866
  * @class
1844
1867
  */
1845
-
1846
1868
  var ColorInputView = Marionette.ItemView.extend({
1847
- mixins: [inputView],
1848
- template: template$6,
1869
+ mixins: [inputView, inputWithPlaceholderText],
1870
+ template: template$8,
1849
1871
  className: 'color_input',
1850
1872
  ui: {
1851
1873
  input: 'input'
@@ -1854,28 +1876,28 @@ var ColorInputView = Marionette.ItemView.extend({
1854
1876
  'mousedown': 'refreshPicker'
1855
1877
  },
1856
1878
  onRender: function onRender() {
1879
+ this.setupAttributeBinding('placeholderColor', this.updatePlaceholderColor);
1857
1880
  this.ui.input.minicolors({
1858
1881
  changeDelay: 200,
1859
1882
  change: _.bind(function (color) {
1860
1883
  this._saving = true;
1861
-
1862
1884
  if (color === this.defaultValue()) {
1863
1885
  this.model.unset(this.options.propertyName);
1864
1886
  } else {
1865
1887
  this.model.set(this.options.propertyName, color);
1866
1888
  }
1867
-
1868
1889
  this._saving = false;
1869
1890
  }, this)
1870
1891
  });
1871
1892
  this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
1872
-
1873
1893
  if (this.options.defaultValueBinding) {
1874
1894
  this.listenTo(this.model, 'change:' + this.options.defaultValueBinding, this.updateSettings);
1875
1895
  }
1876
-
1877
1896
  this.updateSettings();
1878
1897
  },
1898
+ updatePlaceholderColor: function updatePlaceholderColor(value) {
1899
+ this.el.style.setProperty('--placeholder-color', value);
1900
+ },
1879
1901
  updateSettings: function updateSettings() {
1880
1902
  this.resetSwatchesInStoredSettings();
1881
1903
  this.ui.input.minicolors('settings', {
@@ -1887,7 +1909,6 @@ var ColorInputView = Marionette.ItemView.extend({
1887
1909
  // see https://github.com/claviska/jquery-minicolors/issues/287
1888
1910
  resetSwatchesInStoredSettings: function resetSwatchesInStoredSettings() {
1889
1911
  var settings = this.ui.input.data('minicolors-settings');
1890
-
1891
1912
  if (settings) {
1892
1913
  delete settings.swatches;
1893
1914
  this.ui.input.data('minicolors-settings', settings);
@@ -1897,7 +1918,6 @@ var ColorInputView = Marionette.ItemView.extend({
1897
1918
  if (!this._saving) {
1898
1919
  this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
1899
1920
  }
1900
-
1901
1921
  this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
1902
1922
  },
1903
1923
  refreshPicker: function refreshPicker() {
@@ -1908,11 +1928,9 @@ var ColorInputView = Marionette.ItemView.extend({
1908
1928
  },
1909
1929
  defaultValue: function defaultValue() {
1910
1930
  var bindingValue;
1911
-
1912
1931
  if (this.options.defaultValueBinding) {
1913
1932
  bindingValue = this.model.get(this.options.defaultValueBinding);
1914
1933
  }
1915
-
1916
1934
  if (typeof this.options.defaultValue === 'function') {
1917
1935
  return this.options.defaultValue(bindingValue);
1918
1936
  } else if ('defaultValue' in this.options) {
@@ -1923,7 +1941,7 @@ var ColorInputView = Marionette.ItemView.extend({
1923
1941
  }
1924
1942
  });
1925
1943
 
1926
- function template$7(data) {
1944
+ function template$9(data) {
1927
1945
  var __p = '';
1928
1946
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<select></select>';
1929
1947
  return __p
@@ -1938,6 +1956,9 @@ return __p
1938
1956
  * @param {string[]} [options.values]
1939
1957
  * List of possible values to persist in the attribute.
1940
1958
  *
1959
+ * @param {number} [options.defaultValue]
1960
+ * Default value to display if property is not set.
1961
+ *
1941
1962
  * @param {string[]} [options.texts]
1942
1963
  * List of display texts for drop down items.
1943
1964
  *
@@ -1985,7 +2006,10 @@ return __p
1985
2006
  * Display text for the blank item.
1986
2007
  *
1987
2008
  * @param {string} [options.blankTranslationKey]
1988
- * Translation key to obtain display text for blank item.
2009
+ * Translation key to obtain display text for blank item. If neither
2010
+ * `blankText` nor `blankTranslationKey` are provided, the blank text
2011
+ * will be determined using `attributeTranslationKeyPrefixes` with
2012
+ * the suffix `blank`, similar to how labels are determined.
1989
2013
  *
1990
2014
  * @param {string} [options.placeholderValue]
1991
2015
  * Include an item that sets the value of the attribute to a blank
@@ -2007,10 +2031,9 @@ return __p
2007
2031
  *
2008
2032
  * @class
2009
2033
  */
2010
-
2011
2034
  var SelectInputView = Marionette.ItemView.extend({
2012
2035
  mixins: [inputView],
2013
- template: template$7,
2036
+ template: template$9,
2014
2037
  events: {
2015
2038
  'change': 'save'
2016
2039
  },
@@ -2021,20 +2044,17 @@ var SelectInputView = Marionette.ItemView.extend({
2021
2044
  initialize: function initialize() {
2022
2045
  if (this.options.collection) {
2023
2046
  this.options.values = _.pluck(this.options.collection, this.options.valueProperty);
2024
-
2025
2047
  if (this.options.textProperty) {
2026
2048
  this.options.texts = _.pluck(this.options.collection, this.options.textProperty);
2027
2049
  } else if (this.options.translationKeyProperty) {
2028
2050
  this.options.translationKeys = _.pluck(this.options.collection, this.options.translationKeyProperty);
2029
2051
  }
2030
-
2031
2052
  if (this.options.groupProperty) {
2032
2053
  this.options.groups = _.pluck(this.options.collection, this.options.groupProperty);
2033
2054
  } else if (this.options.groupTranslationKeyProperty) {
2034
2055
  this.options.groupTanslationKeys = _.pluck(this.options.collection, this.options.groupTranslationKeyProperty);
2035
2056
  }
2036
2057
  }
2037
-
2038
2058
  if (!this.options.texts) {
2039
2059
  if (!this.options.translationKeys) {
2040
2060
  var translationKeyPrefix = this.options.translationKeyPrefix || findKeyWithTranslation(this.attributeTranslationKeys('values', {
@@ -2044,18 +2064,15 @@ var SelectInputView = Marionette.ItemView.extend({
2044
2064
  return translationKeyPrefix + '.' + value;
2045
2065
  }, this);
2046
2066
  }
2047
-
2048
2067
  this.options.texts = _.map(this.options.translationKeys, function (key) {
2049
2068
  return I18n$1.t(key);
2050
2069
  });
2051
2070
  }
2052
-
2053
2071
  if (!this.options.groups) {
2054
2072
  this.options.groups = _.map(this.options.groupTanslationKeys, function (key) {
2055
2073
  return I18n$1.t(key);
2056
2074
  });
2057
2075
  }
2058
-
2059
2076
  this.optGroups = {};
2060
2077
  },
2061
2078
  onRender: function onRender() {
@@ -2064,7 +2081,6 @@ var SelectInputView = Marionette.ItemView.extend({
2064
2081
  this.appendOptions();
2065
2082
  this.load();
2066
2083
  this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
2067
-
2068
2084
  if (this.options.ensureValueDefined && !this.model.has(this.options.propertyName)) {
2069
2085
  this.save();
2070
2086
  }
@@ -2073,24 +2089,25 @@ var SelectInputView = Marionette.ItemView.extend({
2073
2089
  if (!this.options.includeBlank) {
2074
2090
  return;
2075
2091
  }
2076
-
2092
+ var blankText = this.options.blankText;
2077
2093
  if (this.options.blankTranslationKey) {
2078
- this.options.blankText = I18n$1.t(this.options.blankTranslationKey);
2094
+ blankText = I18n$1.t(this.options.blankTranslationKey);
2095
+ } else if (!blankText) {
2096
+ blankText = findTranslation(this.attributeTranslationKeys('blank'), {
2097
+ defaultValue: I18n$1.t('pageflow.ui.views.inputs.select_input_view.none')
2098
+ });
2079
2099
  }
2080
-
2081
2100
  var option = document.createElement('option');
2082
2101
  option.value = '';
2083
- option.text = this.options.blankText || I18n$1.t('pageflow.ui.views.inputs.select_input_view.none');
2102
+ option.text = blankText;
2084
2103
  this.ui.select.append(option);
2085
2104
  },
2086
2105
  appendPlaceholder: function appendPlaceholder() {
2087
2106
  if (!this.options.placeholderModel && !this.options.placeholderValue) {
2088
2107
  return;
2089
2108
  }
2090
-
2091
2109
  var placeholderValue = this.options.placeholderValue || this.options.placeholderModel.get(this.options.propertyName);
2092
2110
  var placeholderIndex = this.options.values.indexOf(placeholderValue);
2093
-
2094
2111
  if (placeholderIndex >= 0) {
2095
2112
  var option = document.createElement('option');
2096
2113
  option.value = '';
@@ -2106,11 +2123,9 @@ var SelectInputView = Marionette.ItemView.extend({
2106
2123
  var group = this.options.groups[index];
2107
2124
  option.value = value;
2108
2125
  option.text = this.options.texts[index];
2109
-
2110
2126
  if (this.options.optionDisabled && this.options.optionDisabled(value)) {
2111
2127
  option.setAttribute('disabled', true);
2112
2128
  }
2113
-
2114
2129
  if (group) {
2115
2130
  option.setAttribute('data-group', group);
2116
2131
  this.findOrCreateOptGroup(group).append(option);
@@ -2125,18 +2140,23 @@ var SelectInputView = Marionette.ItemView.extend({
2125
2140
  label: label
2126
2141
  }).appendTo(this.ui.select);
2127
2142
  }
2128
-
2129
2143
  return this.optGroups[label];
2130
2144
  },
2131
2145
  save: function save() {
2132
- this.model.set(this.options.propertyName, this.ui.select.val());
2146
+ var value = this.ui.select.val();
2147
+ if ('defaultValue' in this.options && value === this.options.defaultValue) {
2148
+ this.model.unset(this.options.propertyName);
2149
+ } else {
2150
+ this.model.set(this.options.propertyName, value);
2151
+ }
2133
2152
  },
2134
2153
  load: function load() {
2135
2154
  if (!this.isClosed) {
2136
2155
  var value = this.model.get(this.options.propertyName);
2137
-
2138
2156
  if (this.model.has(this.options.propertyName) && this.ui.select.find('option[value="' + value + '"]:not([disabled])').length) {
2139
2157
  this.ui.select.val(value);
2158
+ } else if ('defaultValue' in this.options) {
2159
+ this.ui.select.val(this.options.defaultValue);
2140
2160
  } else {
2141
2161
  this.ui.select.val(this.ui.select.find('option:not([disabled]):first').val());
2142
2162
  }
@@ -2148,7 +2168,6 @@ var ExtendedSelectInputView = SelectInputView.extend({
2148
2168
  className: 'extended_select_input',
2149
2169
  initialize: function initialize() {
2150
2170
  SelectInputView.prototype.initialize.apply(this, arguments);
2151
-
2152
2171
  if (this.options.collection) {
2153
2172
  if (this.options.descriptionProperty) {
2154
2173
  this.options.descriptions = _.pluck(this.options.collection, this.options.descriptionProperty);
@@ -2156,7 +2175,6 @@ var ExtendedSelectInputView = SelectInputView.extend({
2156
2175
  this.options.descriptionTanslationKeys = _.pluck(this.options.collection, this.options.descriptionTranslationKeyProperty);
2157
2176
  }
2158
2177
  }
2159
-
2160
2178
  if (!this.options.descriptions) {
2161
2179
  this.options.descriptions = _.map(this.options.descriptionTanslationKeys, function (key) {
2162
2180
  return I18n$1.t(key);
@@ -2165,7 +2183,7 @@ var ExtendedSelectInputView = SelectInputView.extend({
2165
2183
  },
2166
2184
  onRender: function onRender() {
2167
2185
  var view = this,
2168
- options = this.options;
2186
+ options = this.options;
2169
2187
  SelectInputView.prototype.onRender.apply(this, arguments);
2170
2188
  $.widget("custom.extendedselectmenu", $.ui.selectmenu, {
2171
2189
  _renderItem: function _renderItem(ul, item) {
@@ -2177,17 +2195,14 @@ var ExtendedSelectInputView = SelectInputView.extend({
2177
2195
  "class": 'text-container'
2178
2196
  }).appendTo(li);
2179
2197
  var index = options.values.indexOf(item.value);
2180
-
2181
2198
  if (item.disabled) {
2182
2199
  li.addClass('ui-state-disabled');
2183
2200
  }
2184
-
2185
2201
  if (options.pictogramClass) {
2186
2202
  $('<span>', {
2187
2203
  "class": options.pictogramClass
2188
2204
  }).prependTo(li);
2189
2205
  }
2190
-
2191
2206
  $('<p>', {
2192
2207
  text: item.label,
2193
2208
  "class": 'item-text'
@@ -2196,7 +2211,6 @@ var ExtendedSelectInputView = SelectInputView.extend({
2196
2211
  text: options.descriptions[index],
2197
2212
  "class": 'item-description'
2198
2213
  }).appendTo(container);
2199
-
2200
2214
  if (options.helpLinkClicked) {
2201
2215
  $('<a>', {
2202
2216
  href: '#',
@@ -2207,15 +2221,13 @@ var ExtendedSelectInputView = SelectInputView.extend({
2207
2221
  return false;
2208
2222
  }).appendTo(li);
2209
2223
  }
2210
-
2211
2224
  return li.appendTo(ul);
2212
2225
  },
2213
2226
  _resizeMenu: function _resizeMenu() {
2214
2227
  this.menuWrap.addClass('extended_select_input_menu');
2215
2228
  var menuHeight = this.menu.height(),
2216
- menuOffset = this.button.offset().top + this.button.outerHeight(),
2217
- bodyHeight = $('body').height();
2218
-
2229
+ menuOffset = this.button.offset().top + this.button.outerHeight(),
2230
+ bodyHeight = $('body').height();
2219
2231
  if (menuHeight + menuOffset > bodyHeight) {
2220
2232
  this.menuWrap.outerHeight(bodyHeight - menuOffset - 5).css({
2221
2233
  'overflow-y': 'scroll'
@@ -2243,7 +2255,7 @@ var ExtendedSelectInputView = SelectInputView.extend({
2243
2255
  }
2244
2256
  });
2245
2257
 
2246
- function template$8(data) {
2258
+ function template$a(data) {
2247
2259
  var __t, __p = '';
2248
2260
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<!-- inline style for wysihtml5 to pick up -->\n<textarea style="width: 100%;" dir="auto"></textarea>\n\n<div class="toolbar">\n <a data-wysihtml5-command="bold" title="' +
2249
2261
  ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.bold') )) == null ? '' : __t) +
@@ -2300,10 +2312,9 @@ return __p
2300
2312
  *
2301
2313
  * @class
2302
2314
  */
2303
-
2304
2315
  var TextAreaInputView = Marionette.ItemView.extend({
2305
2316
  mixins: [inputView, inputWithPlaceholderText],
2306
- template: template$8,
2317
+ template: template$a,
2307
2318
  className: 'text_area_input',
2308
2319
  ui: {
2309
2320
  input: 'textarea',
@@ -2376,7 +2387,6 @@ var TextAreaInputView = Marionette.ItemView.extend({
2376
2387
  }
2377
2388
  }
2378
2389
  });
2379
-
2380
2390
  if (this.options.disableRichtext) {
2381
2391
  this.ui.toolbar.find('a[data-wysihtml5-command="bold"]').hide();
2382
2392
  this.ui.toolbar.find('a[data-wysihtml5-command="italic"]').hide();
@@ -2384,19 +2394,16 @@ var TextAreaInputView = Marionette.ItemView.extend({
2384
2394
  this.ui.toolbar.find('a[data-wysihtml5-command="insertOrderedList"]').hide();
2385
2395
  this.ui.toolbar.find('a[data-wysihtml5-command="insertUnorderedList"]').hide();
2386
2396
  }
2387
-
2388
2397
  if (!this.options.enableLists) {
2389
2398
  this.ui.toolbar.find('a[data-wysihtml5-command="insertOrderedList"]').hide();
2390
2399
  this.ui.toolbar.find('a[data-wysihtml5-command="insertUnorderedList"]').hide();
2391
2400
  }
2392
-
2393
2401
  if (this.options.disableLinks) {
2394
2402
  this.ui.toolbar.find('a[data-wysihtml5-command="createLink"]').hide();
2395
2403
  } else {
2396
2404
  this.setupUrlLinkPanel();
2397
2405
  this.setupFragmentLinkPanel();
2398
2406
  }
2399
-
2400
2407
  this.editor.on('change', _.bind(this.save, this));
2401
2408
  this.editor.on('aftercommand:composer', _.bind(this.save, this));
2402
2409
  },
@@ -2413,7 +2420,6 @@ var TextAreaInputView = Marionette.ItemView.extend({
2413
2420
  this.editor.on('show:dialog', _.bind(function () {
2414
2421
  this.ui.linkDialog.toggleClass('for_existing_link', this.ui.linkButton.hasClass('wysihtml5-command-active'));
2415
2422
  var currentUrl = this.ui.urlInput.val();
2416
-
2417
2423
  if (currentUrl.startsWith('#')) {
2418
2424
  this.ui.displayUrlInput.val('');
2419
2425
  this.ui.openInNewTabCheckBox.prop('checked', true);
@@ -2457,7 +2463,6 @@ var TextAreaInputView = Marionette.ItemView.extend({
2457
2463
  } else {
2458
2464
  this.ui.fragmentLinkRadioButton.prop('checked', true);
2459
2465
  }
2460
-
2461
2466
  this.ui.toolbar.toggleClass('fragment_link_panel_active', !isUrlLink);
2462
2467
  },
2463
2468
  showUrlLinkPanel: function showUrlLinkPanel() {
@@ -2481,7 +2486,7 @@ var TextAreaInputView = Marionette.ItemView.extend({
2481
2486
  }
2482
2487
  });
2483
2488
 
2484
- function template$9(data) {
2489
+ function template$b(data) {
2485
2490
  var __p = '';
2486
2491
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" />\n<div class="validation"></div>\n';
2487
2492
  return __p
@@ -2504,12 +2509,9 @@ return __p
2504
2509
  *
2505
2510
  * @class
2506
2511
  */
2507
-
2508
- var UrlInputView = Marionette.Layout.extend(
2509
- /** @lends UrlInputView.prototype */
2510
- {
2512
+ var UrlInputView = Marionette.Layout.extend( /** @lends UrlInputView.prototype */{
2511
2513
  mixins: [inputView],
2512
- template: template$9,
2514
+ template: template$b,
2513
2515
  ui: {
2514
2516
  input: 'input',
2515
2517
  validation: '.validation'
@@ -2524,7 +2526,6 @@ var UrlInputView = Marionette.Layout.extend(
2524
2526
  },
2525
2527
  onChange: function onChange() {
2526
2528
  var _this = this;
2527
-
2528
2529
  this.validate().then(function () {
2529
2530
  return _this.save();
2530
2531
  }, function () {
@@ -2539,24 +2540,19 @@ var UrlInputView = Marionette.Layout.extend(
2539
2540
  },
2540
2541
  save: function save() {
2541
2542
  var _this2 = this;
2542
-
2543
2543
  var value = this.ui.input.val();
2544
2544
  $.when(this.transformPropertyValue(value)).then(function (transformedValue) {
2545
- var _this2$model$set;
2546
-
2547
- _this2.model.set((_this2$model$set = {}, _defineProperty(_this2$model$set, _this2.options.displayPropertyName, value), _defineProperty(_this2$model$set, _this2.options.propertyName, transformedValue), _this2$model$set));
2545
+ _this2.model.set(_defineProperty(_defineProperty({}, _this2.options.displayPropertyName, value), _this2.options.propertyName, transformedValue));
2548
2546
  });
2549
2547
  },
2550
2548
  load: function load() {
2551
2549
  this.ui.input.val(this.model.has(this.options.displayPropertyName) ? this.model.get(this.options.displayPropertyName) : this.model.get(this.options.propertyName));
2552
2550
  this.onLoad();
2553
2551
  },
2554
-
2555
2552
  /**
2556
2553
  * Override to be notified when the input has been loaded.
2557
2554
  */
2558
2555
  onLoad: function onLoad() {},
2559
-
2560
2556
  /**
2561
2557
  * Override to validate the untransformed url. Validation error
2562
2558
  * message can be passed as rejected promise. Progress notifications
@@ -2567,7 +2563,6 @@ var UrlInputView = Marionette.Layout.extend(
2567
2563
  validateUrl: function validateUrl(url) {
2568
2564
  return $.Deferred().resolve().promise();
2569
2565
  },
2570
-
2571
2566
  /**
2572
2567
  * Override to transform the property value before it is stored.
2573
2568
  *
@@ -2576,7 +2571,6 @@ var UrlInputView = Marionette.Layout.extend(
2576
2571
  transformPropertyValue: function transformPropertyValue(value) {
2577
2572
  return value;
2578
2573
  },
2579
-
2580
2574
  /**
2581
2575
  * Override to change the list of supported host names.
2582
2576
  */
@@ -2596,16 +2590,13 @@ var UrlInputView = Marionette.Layout.extend(
2596
2590
  var view = this;
2597
2591
  var options = this.options;
2598
2592
  var value = this.ui.input.val();
2599
-
2600
2593
  if (options.required && !value) {
2601
2594
  displayValidationError(I18n$1.t('pageflow.ui.views.inputs.url_input_view.required_field'));
2602
2595
  } else if (value && !isValidUrl(value)) {
2603
2596
  var errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint');
2604
-
2605
2597
  if (options.permitHttps) {
2606
2598
  errorMessage = I18n$1.t('pageflow.ui.views.inputs.url_input_view.url_hint_https');
2607
2599
  }
2608
-
2609
2600
  displayValidationError(errorMessage);
2610
2601
  } else if (value && !hasSupportedHost(value)) {
2611
2602
  displayValidationError(I18n$1.t('pageflow.ui.views.inputs.url_input_view.supported_vendors') + _.map(view.supportedHosts(), function (url) {
@@ -2620,31 +2611,25 @@ var UrlInputView = Marionette.Layout.extend(
2620
2611
  displayValidationError(error);
2621
2612
  });
2622
2613
  }
2623
-
2624
2614
  return $.Deferred().reject().promise();
2625
-
2626
2615
  function isValidUrl(url) {
2627
2616
  return options.permitHttps ? url.match(/^https?:\/\//i) : url.match(/^http:\/\//i);
2628
2617
  }
2629
-
2630
2618
  function hasSupportedHost(url) {
2631
2619
  return _.any(view.supportedHostsWithoutLegacyProtocols(), function (host) {
2632
2620
  return url.match(new RegExp('^https?://' + host));
2633
2621
  });
2634
2622
  }
2635
-
2636
2623
  function displayValidationError(message) {
2637
2624
  view.$el.addClass('invalid');
2638
2625
  view.ui.input.attr('aria-invalid', 'true');
2639
2626
  view.ui.validation.removeClass('pending').addClass('failed').html(message).show();
2640
2627
  }
2641
-
2642
2628
  function displayValidationPending(message) {
2643
2629
  view.$el.removeClass('invalid');
2644
2630
  view.ui.input.removeAttr('aria-invalid');
2645
2631
  view.ui.validation.removeClass('failed').addClass('pending').html(message).show();
2646
2632
  }
2647
-
2648
2633
  function resetValidationError(message) {
2649
2634
  view.$el.removeClass('invalid');
2650
2635
  view.ui.input.attr('aria-invalid', 'false');
@@ -2699,10 +2684,7 @@ var UrlInputView = Marionette.Layout.extend(
2699
2684
  *
2700
2685
  * @class
2701
2686
  */
2702
-
2703
- var ProxyUrlInputView = UrlInputView.extend(
2704
- /** @lends ProxyUrlInputView.prototype */
2705
- {
2687
+ var ProxyUrlInputView = UrlInputView.extend( /** @lends ProxyUrlInputView.prototype */{
2706
2688
  // @override
2707
2689
  validateUrl: function validateUrl(url) {
2708
2690
  var view = this;
@@ -2730,12 +2712,11 @@ var ProxyUrlInputView = UrlInputView.extend(
2730
2712
  _.each(this.options.proxies, function (proxy) {
2731
2713
  url = url.replace(new RegExp('^' + proxy.url + '/?'), proxy.base_path + '/');
2732
2714
  });
2733
-
2734
2715
  return url;
2735
2716
  }
2736
2717
  });
2737
2718
 
2738
- function template$a(data) {
2719
+ function template$c(data) {
2739
2720
  var __p = '';
2740
2721
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="value"></div>\n<div class="slider"></div>\n';
2741
2722
  return __p
@@ -2748,7 +2729,7 @@ return __p
2748
2729
  * @param {Object} [options]
2749
2730
  *
2750
2731
  * @param {number} [options.defaultValue]
2751
- * Defaults value to display if property is not set.
2732
+ * Default value to display if property is not set.
2752
2733
  *
2753
2734
  * @param {number} [options.minValue=0]
2754
2735
  * Value when dragging slider to the very left.
@@ -2768,11 +2749,10 @@ return __p
2768
2749
  *
2769
2750
  * @class
2770
2751
  */
2771
-
2772
2752
  var SliderInputView = Marionette.ItemView.extend({
2773
2753
  mixins: [inputView],
2774
2754
  className: 'slider_input',
2775
- template: template$a,
2755
+ template: template$c,
2776
2756
  ui: {
2777
2757
  widget: '.slider',
2778
2758
  value: '.value'
@@ -2783,7 +2763,6 @@ var SliderInputView = Marionette.ItemView.extend({
2783
2763
  },
2784
2764
  onRender: function onRender() {
2785
2765
  var _this = this;
2786
-
2787
2766
  this.ui.widget.slider({
2788
2767
  animate: 'fast'
2789
2768
  });
@@ -2791,7 +2770,7 @@ var SliderInputView = Marionette.ItemView.extend({
2791
2770
  return _this.updateSliderOption('min', value || 0);
2792
2771
  });
2793
2772
  this.setupAttributeBinding('maxValue', function (value) {
2794
- return _this.updateSliderOption('max', value || 100);
2773
+ return _this.updateSliderOption('max', value !== undefined ? value : 100);
2795
2774
  });
2796
2775
  this.load();
2797
2776
  this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
@@ -2802,7 +2781,6 @@ var SliderInputView = Marionette.ItemView.extend({
2802
2781
  },
2803
2782
  updateDisabled: function updateDisabled(disabled) {
2804
2783
  this.$el.toggleClass('disabled', !!disabled);
2805
-
2806
2784
  if (disabled) {
2807
2785
  this.ui.widget.slider('disable');
2808
2786
  } else {
@@ -2811,7 +2789,6 @@ var SliderInputView = Marionette.ItemView.extend({
2811
2789
  },
2812
2790
  handleSlide: function handleSlide(event, ui) {
2813
2791
  this.updateText(ui.value);
2814
-
2815
2792
  if (this.options.saveOnSlide) {
2816
2793
  this.save(event, ui);
2817
2794
  }
@@ -2821,13 +2798,11 @@ var SliderInputView = Marionette.ItemView.extend({
2821
2798
  },
2822
2799
  load: function load() {
2823
2800
  var value;
2824
-
2825
2801
  if (this.model.has(this.options.propertyName)) {
2826
2802
  value = this.model.get(this.options.propertyName);
2827
2803
  } else {
2828
2804
  value = 'defaultValue' in this.options ? this.options.defaultValue : 0;
2829
2805
  }
2830
-
2831
2806
  this.ui.widget.slider('option', 'value', this.clampValue(value));
2832
2807
  this.updateText(value);
2833
2808
  },
@@ -2843,7 +2818,7 @@ var SliderInputView = Marionette.ItemView.extend({
2843
2818
  }
2844
2819
  });
2845
2820
 
2846
- function template$b(data) {
2821
+ function template$d(data) {
2847
2822
  var __p = '';
2848
2823
  __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<textarea></textarea>\n';
2849
2824
  return __p
@@ -2851,7 +2826,7 @@ return __p
2851
2826
 
2852
2827
  var JsonInputView = Marionette.ItemView.extend({
2853
2828
  mixins: [inputView],
2854
- template: template$b,
2829
+ template: template$d,
2855
2830
  className: 'json_input',
2856
2831
  ui: {
2857
2832
  input: 'textarea'
@@ -2885,7 +2860,6 @@ var JsonInputView = Marionette.ItemView.extend({
2885
2860
  },
2886
2861
  validate: function validate() {
2887
2862
  var input = this.ui.input;
2888
-
2889
2863
  if (input.val() && !this.isValidJson(input.val())) {
2890
2864
  this.displayValidationError(I18n$1.t('pageflow.ui.views.inputs.json_input_view.invalid'));
2891
2865
  return false;
@@ -2912,7 +2886,7 @@ var JsonInputView = Marionette.ItemView.extend({
2912
2886
  }
2913
2887
  });
2914
2888
 
2915
- function template$c(data) {
2889
+ function template$e(data) {
2916
2890
  var __p = '';
2917
2891
  __p += '<input type="checkbox" />\n<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>';
2918
2892
  return __p
@@ -2939,10 +2913,9 @@ return __p
2939
2913
  *
2940
2914
  * @class
2941
2915
  */
2942
-
2943
2916
  var CheckBoxInputView = Marionette.ItemView.extend({
2944
2917
  mixins: [inputView],
2945
- template: template$c,
2918
+ template: template$e,
2946
2919
  className: 'check_box_input',
2947
2920
  events: {
2948
2921
  'change': 'save'
@@ -2963,7 +2936,6 @@ var CheckBoxInputView = Marionette.ItemView.extend({
2963
2936
  save: function save() {
2964
2937
  if (!this.isDisabled()) {
2965
2938
  var value = this.ui.input.is(':checked');
2966
-
2967
2939
  if (this.options.storeInverted) {
2968
2940
  this.model.set(this.options.storeInverted, !value);
2969
2941
  } else {
@@ -2973,7 +2945,7 @@ var CheckBoxInputView = Marionette.ItemView.extend({
2973
2945
  },
2974
2946
  load: function load() {
2975
2947
  if (!this.isClosed) {
2976
- this.ui.input.prop('checked', this.displayValue());
2948
+ this.ui.input.prop('checked', !!this.displayValue());
2977
2949
  }
2978
2950
  },
2979
2951
  displayValue: function displayValue() {
@@ -2998,7 +2970,6 @@ var CheckBoxInputView = Marionette.ItemView.extend({
2998
2970
  *
2999
2971
  * @class
3000
2972
  */
3001
-
3002
2973
  var SeparatorView = Marionette.View.extend({
3003
2974
  className: 'separator'
3004
2975
  });
@@ -3011,7 +2982,6 @@ var SeparatorView = Marionette.View.extend({
3011
2982
  *
3012
2983
  * @class
3013
2984
  */
3014
-
3015
2985
  var LabelOnlyView = Marionette.ItemView.extend({
3016
2986
  mixins: [inputView],
3017
2987
  template: function template() {
@@ -3037,7 +3007,6 @@ var LabelOnlyView = Marionette.ItemView.extend({
3037
3007
  *
3038
3008
  * @since 12.0
3039
3009
  */
3040
-
3041
3010
  var EnumTableCellView = TableCellView.extend({
3042
3011
  className: 'enum_table_cell',
3043
3012
  update: function update() {
@@ -3048,7 +3017,7 @@ var EnumTableCellView = TableCellView.extend({
3048
3017
  }
3049
3018
  });
3050
3019
 
3051
- function template$d(data) {
3020
+ function template$f(data) {
3052
3021
  var __t, __p = '';
3053
3022
  __p += '<a class="remove" title="' +
3054
3023
  ((__t = ( I18n.t('pageflow.editor.templates.row.destroy') )) == null ? '' : __t) +
@@ -3078,10 +3047,9 @@ return __p
3078
3047
  *
3079
3048
  * @since 12.0
3080
3049
  */
3081
-
3082
3050
  var DeleteRowTableCellView = TableCellView.extend({
3083
3051
  className: 'delete_row_table_cell',
3084
- template: template$d,
3052
+ template: template$f,
3085
3053
  ui: {
3086
3054
  removeButton: '.remove'
3087
3055
  },
@@ -3095,7 +3063,6 @@ var DeleteRowTableCellView = TableCellView.extend({
3095
3063
  if (this.options.toggleDeleteButton) {
3096
3064
  var context = this.getModel();
3097
3065
  var toggle = context[this.options.toggleDeleteButton].apply(context);
3098
-
3099
3066
  if (this.options.invertToggleDeleteButton) {
3100
3067
  return !toggle;
3101
3068
  } else {
@@ -3130,7 +3097,6 @@ var DeleteRowTableCellView = TableCellView.extend({
3130
3097
  *
3131
3098
  * @since 12.0
3132
3099
  */
3133
-
3134
3100
  var PresenceTableCellView = TableCellView.extend({
3135
3101
  className: 'presence_table_cell',
3136
3102
  update: function update() {
@@ -3162,7 +3128,6 @@ var PresenceTableCellView = TableCellView.extend({
3162
3128
  *
3163
3129
  * @since 12.0
3164
3130
  */
3165
-
3166
3131
  var IconTableCellView = TableCellView.extend({
3167
3132
  className: 'icon_table_cell',
3168
3133
  update: function update() {
@@ -3198,7 +3163,6 @@ var IconTableCellView = TableCellView.extend({
3198
3163
  *
3199
3164
  * @since 12.0
3200
3165
  */
3201
-
3202
3166
  var TextTableCellView = TableCellView.extend({
3203
3167
  className: 'text_table_cell',
3204
3168
  update: function update() {
@@ -3209,14 +3173,12 @@ var TextTableCellView = TableCellView.extend({
3209
3173
  return this.attributeValue();
3210
3174
  } else if (typeof this.options.column["default"] === 'function') {
3211
3175
  var options = {};
3212
-
3213
3176
  if (this.options.column.contentBinding) {
3214
3177
  options = {
3215
3178
  contentBinding: this.options.column.contentBinding,
3216
3179
  model: this.getModel()
3217
3180
  };
3218
3181
  }
3219
-
3220
3182
  return this.options.column["default"](options);
3221
3183
  } else if ('default' in this.options.column) {
3222
3184
  return this.options.column["default"];
@@ -3234,8 +3196,7 @@ var subviewContainer = {
3234
3196
  },
3235
3197
  appendSubview: function appendSubview(view) {
3236
3198
  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
3237
- to = _ref.to;
3238
-
3199
+ to = _ref.to;
3239
3200
  return (to || this.$el).append(this.subview(view).el);
3240
3201
  },
3241
3202
  onClose: function onClose() {
@@ -3244,7 +3205,6 @@ var subviewContainer = {
3244
3205
  }
3245
3206
  }
3246
3207
  };
3247
-
3248
3208
  if (!Marionette.View.prototype.appendSubview) {
3249
3209
  Cocktail.mixin(Marionette.View, subviewContainer);
3250
3210
  }
@@ -3256,7 +3216,6 @@ var tooltipContainer = {
3256
3216
  var target = $(event.currentTarget);
3257
3217
  var key = target.attr('data-tooltip');
3258
3218
  var position;
3259
-
3260
3219
  if (target.data('tooltipAlign') === 'bottom left') {
3261
3220
  position = {
3262
3221
  left: target.position().left,
@@ -3278,7 +3237,6 @@ var tooltipContainer = {
3278
3237
  top: target.position().top + target.outerHeight() / 2
3279
3238
  };
3280
3239
  }
3281
-
3282
3240
  this.tooltip.show(I18n$1.t(key), position, {
3283
3241
  align: target.data('tooltipAlign')
3284
3242
  });
@@ -3293,4 +3251,4 @@ var tooltipContainer = {
3293
3251
  }
3294
3252
  };
3295
3253
 
3296
- export { CheckBoxGroupInputView, CheckBoxInputView, CollectionView, ColorInputView, ConfigurationEditorTabView, ConfigurationEditorView, DeleteRowTableCellView, EnumTableCellView, ExtendedSelectInputView, IconTableCellView, JsonInputView, LabelOnlyView, NumberInputView, BaseObject as Object, PresenceTableCellView, ProxyUrlInputView, SelectInputView, SeparatorView, SliderInputView, SortableCollectionView, TableCellView, TableHeaderCellView, TableRowView, TableView, TabsView, TextAreaInputView, TextInputView, TextTableCellView, TooltipView, UrlDisplayView, UrlInputView, attributeBinding, cssModulesUtils, i18nUtils, inputView, inputWithPlaceholderText, serverSideValidation, subviewContainer, tooltipContainer, viewWithValidationErrorMessages };
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 };