pageflow 15.2.0 → 15.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pageflow might be problematic. Click here for more details.

Files changed (214) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +89 -83
  3. data/README.md +2 -3
  4. data/admins/pageflow/accounts.rb +1 -98
  5. data/admins/pageflow/entry.rb +21 -1
  6. data/admins/pageflow/entry_templates.rb +140 -0
  7. data/admins/pageflow/membership.rb +12 -0
  8. data/admins/pageflow/user.rb +5 -5
  9. data/app/assets/javascripts/pageflow/admin/accounts.js +1 -1
  10. data/app/assets/javascripts/pageflow/admin/entries.js +65 -0
  11. data/app/assets/javascripts/pageflow/admin/users.js +1 -1
  12. data/app/assets/javascripts/pageflow/asset_urls.js.erb +1 -0
  13. data/app/assets/javascripts/pageflow/base.js +0 -12
  14. data/app/assets/javascripts/pageflow/components.js +2 -6
  15. data/app/assets/javascripts/pageflow/dist/ui.js +178 -55
  16. data/app/assets/javascripts/pageflow/editor/vendor.js +1 -0
  17. data/app/assets/javascripts/pageflow/vendor.js +12 -10
  18. data/app/assets/stylesheets/pageflow/base.scss +0 -7
  19. data/app/assets/stylesheets/pageflow/editor/base.scss +5 -2
  20. data/app/assets/stylesheets/pageflow/editor/composables.scss +5 -1
  21. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +1 -1
  22. data/app/assets/stylesheets/pageflow/editor/emulation_mode_button.scss +44 -55
  23. data/app/assets/stylesheets/pageflow/editor/help.scss +2 -2
  24. data/app/assets/stylesheets/pageflow/editor/select_button.scss +1 -1
  25. data/app/assets/stylesheets/pageflow/editor/sidebar_footer.scss +1 -1
  26. data/app/assets/stylesheets/pageflow/entries.scss +1 -1
  27. data/app/assets/stylesheets/pageflow/loading_spinner.scss +4 -1
  28. data/app/assets/stylesheets/pageflow/navigation_mobile.scss +4 -4
  29. data/app/assets/stylesheets/pageflow/themes/default/anchors.scss +1 -1
  30. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +1 -1
  31. data/app/assets/stylesheets/pageflow/themes/default/page.scss +7 -0
  32. data/app/assets/stylesheets/pageflow/themes/default/page/anchors.scss +1 -1
  33. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/control_bar.scss +1 -1
  34. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/info_box.scss +1 -1
  35. data/app/assets/stylesheets/pageflow/themes/default/player_controls/shared/menu_bar.scss +2 -2
  36. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/control_bar.scss +2 -2
  37. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/info_box.scss +1 -1
  38. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/quality_menu.scss +2 -2
  39. data/app/assets/stylesheets/pageflow/themes/default/player_controls/waveform/wave.scss +1 -1
  40. data/app/assets/stylesheets/pageflow/ui/forms.scss +9 -2
  41. data/app/assets/stylesheets/pageflow/ui/input/extended_select_input.scss +2 -2
  42. data/app/assets/stylesheets/pageflow/ui/tooltip.scss +17 -3
  43. data/app/helpers/pageflow/admin/entries_helper.rb +16 -0
  44. data/app/helpers/pageflow/structured_data_helper.rb +0 -2
  45. data/app/models/pageflow/account.rb +21 -1
  46. data/app/models/pageflow/account_role_query.rb +1 -1
  47. data/app/models/pageflow/chapter.rb +3 -9
  48. data/app/models/pageflow/entry.rb +9 -2
  49. data/app/models/pageflow/entry_duplicate.rb +1 -0
  50. data/app/models/pageflow/entry_template.rb +16 -2
  51. data/app/models/pageflow/managed_user_query.rb +1 -1
  52. data/app/models/pageflow/page.rb +1 -4
  53. data/app/models/pageflow/revision.rb +0 -4
  54. data/app/models/pageflow/storyline.rb +2 -9
  55. data/app/policies/pageflow/account_policy.rb +10 -0
  56. data/app/policies/pageflow/entry_template_policy.rb +5 -1
  57. data/app/policies/pageflow/folder_policy.rb +2 -2
  58. data/app/policies/pageflow/membership_policy.rb +2 -2
  59. data/app/policies/pageflow/theming_policy.rb +2 -2
  60. data/app/policies/pageflow/user_policy.rb +1 -1
  61. data/app/views/admin/accounts/_entry_template_details.html.arb +7 -5
  62. data/app/views/admin/accounts/_form.html.erb +3 -49
  63. data/app/views/admin/entries/_attributes_table.html.arb +5 -0
  64. data/app/views/admin/entries/_not_allowed_to_see_entry_types.json.jbuilder +2 -0
  65. data/app/views/admin/entries/entry_types.json.jbuilder +4 -0
  66. data/app/views/admin/entry_templates/_form.html.erb +58 -0
  67. data/app/views/admin/users/_not_allowed_to_see_user_quota.html.erb +3 -0
  68. data/app/views/components/pageflow/admin/entry_templates_tab.rb +48 -0
  69. data/app/views/pageflow/admin/initial_passwords/edit.html.erb +2 -1
  70. data/app/views/pageflow/admin/users/_quota_exhausted.html.erb +1 -1
  71. data/app/views/pageflow/themes/_theme.json.jbuilder +1 -1
  72. data/app/views/pageflow/video_files/_video_file.json.jbuilder +8 -1
  73. data/config/initializers/admin_resource_tabs.rb +5 -0
  74. data/config/initializers/help_entries.rb +1 -5
  75. data/config/initializers/revision_components.rb +5 -0
  76. data/config/locales/de.yml +88 -155
  77. data/config/locales/en.yml +79 -143
  78. data/db/migrate/20200515112500_add_constraints_to_entry_templates.rb +21 -0
  79. data/db/migrate/20200807135200_rename_pageflow_entry_template_entry_type_to_entry_type_name.rb +7 -0
  80. data/entry_types/paged/app/assets/javascripts/pageflow_paged/components.js +7 -0
  81. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +1528 -1349
  82. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +9258 -0
  83. data/{app/assets/javascripts/pageflow → entry_types/paged/app/assets/javascripts/pageflow_paged}/dist/react-client.js +1 -1
  84. data/{app/assets/javascripts/pageflow → entry_types/paged/app/assets/javascripts/pageflow_paged}/dist/react-server.js +3 -3
  85. data/entry_types/paged/app/assets/javascripts/pageflow_paged/frontend.js +6 -0
  86. data/entry_types/paged/app/assets/javascripts/pageflow_paged/server_rendering.js +9 -0
  87. data/entry_types/paged/app/assets/javascripts/pageflow_paged/vendor.js +9 -0
  88. data/entry_types/paged/app/assets/javascripts/pageflow_paged/videojs.js +6 -0
  89. data/entry_types/paged/app/controllers/pageflow_paged/application_controller.rb +2 -2
  90. data/{app/helpers/pageflow → entry_types/paged/app/helpers/pageflow_paged}/page_background_asset_helper.rb +4 -3
  91. data/{app/helpers/pageflow → entry_types/paged/app/helpers/pageflow_paged}/react_server_side_rendering_helper.rb +23 -2
  92. data/entry_types/paged/app/views/layouts/pageflow_paged/_loading_spinner_inline_script.html.erb +1 -0
  93. data/entry_types/paged/app/views/layouts/pageflow_paged/application.html.erb +3 -3
  94. data/entry_types/paged/app/views/pageflow_paged/editor/entries/_head.html.erb +4 -2
  95. data/entry_types/paged/app/views/pageflow_paged/entries/_entry.html.erb +1 -1
  96. data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/page_background_asset/_element.html.erb +0 -0
  97. data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/react/_widget.html.erb +0 -0
  98. data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/react/page.html.erb +0 -0
  99. data/entry_types/paged/config/initializers/features.rb +1 -1
  100. data/entry_types/paged/config/initializers/help_entries.rb +17 -0
  101. data/entry_types/paged/config/locales/new/help.de.yml +162 -0
  102. data/entry_types/paged/config/locales/new/help.en.yml +153 -0
  103. data/entry_types/paged/lib/pageflow_paged/engine.rb +13 -0
  104. data/entry_types/paged/lib/pageflow_paged/plugin.rb +5 -1
  105. data/entry_types/paged/lib/pageflow_paged/react.rb +12 -0
  106. data/{lib/pageflow → entry_types/paged/lib/pageflow_paged}/react/page_type.rb +2 -2
  107. data/{lib/pageflow → entry_types/paged/lib/pageflow_paged}/react/widget_type.rb +2 -2
  108. data/entry_types/paged/lib/tasks/pageflow_paged_tasks.rake +7 -0
  109. data/entry_types/paged/vendor/assets/javascripts/development/pageflow_paged/vendor/react-server.js +20613 -0
  110. data/entry_types/paged/vendor/assets/javascripts/development/pageflow_paged/vendor/react.js +21495 -0
  111. data/{vendor/assets/javascripts → entry_types/paged/vendor/assets/javascripts/pageflow_paged/vendor}/dash.all.min.js +0 -0
  112. data/{vendor/assets/javascripts → entry_types/paged/vendor/assets/javascripts/pageflow_paged/vendor}/videojs-dash.js +0 -0
  113. data/{vendor/assets/javascripts → entry_types/paged/vendor/assets/javascripts/pageflow_paged/vendor}/videojs.js +0 -0
  114. data/entry_types/paged/vendor/assets/javascripts/production/pageflow_paged/vendor/react-server.js +24 -0
  115. data/entry_types/paged/vendor/assets/javascripts/production/pageflow_paged/vendor/react.js +24 -0
  116. data/entry_types/scrolled/app/assets/javascripts/pageflow_scrolled/legacy.js +0 -0
  117. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +2 -2
  118. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +14 -4
  119. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -2
  120. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +10 -0
  121. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +7 -0
  122. data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +2 -0
  123. data/entry_types/scrolled/app/helpers/pageflow_scrolled/favicon_helper.rb +21 -0
  124. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +40 -0
  125. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +36 -0
  126. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +3 -9
  127. data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +37 -2
  128. data/entry_types/scrolled/app/models/pageflow_scrolled/section.rb +3 -9
  129. data/entry_types/scrolled/app/models/pageflow_scrolled/storyline.rb +1 -9
  130. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/content_elements/batch.json.jbuilder +2 -0
  131. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -7
  132. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/_global_notices.html.erb +10 -0
  133. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +28 -11
  134. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +3 -0
  135. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +8 -0
  136. data/entry_types/scrolled/app/views/pageflow_scrolled/favicons/_entry.html.erb +10 -0
  137. data/entry_types/scrolled/config/initializers/help_entries.rb +16 -0
  138. data/entry_types/scrolled/config/locales/de.yml +669 -0
  139. data/entry_types/scrolled/config/locales/en.yml +488 -0
  140. data/entry_types/scrolled/config/routes.rb +1 -0
  141. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +76 -6
  142. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/android-chrome-192x192.png +0 -0
  143. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/android-chrome-512x512.png +0 -0
  144. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/apple-touch-icon.png +0 -0
  145. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/browserconfig.xml +9 -0
  146. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/favicon-16x16.png +0 -0
  147. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/favicon-32x32.png +0 -0
  148. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/favicon.ico +0 -0
  149. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/mstile-150x150.png +0 -0
  150. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/safari-pinned-tab.svg +46 -0
  151. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/favicons/site.webmanifest +19 -0
  152. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDesktop.svg +56 -0
  153. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoMobile.svg +22 -0
  154. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/unmute.mp3 +0 -0
  155. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/themes_plugin.rb.tt +26 -0
  156. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +4 -0
  157. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +3 -1
  158. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +90 -30
  159. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/create_bundle_symlinks_for_yarn.rake +32 -0
  160. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/dummy.rake +8 -0
  161. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +173 -0
  162. data/entry_types/scrolled/package/contentElements-editor.js +541 -0
  163. data/entry_types/scrolled/package/contentElements-frontend.css +1 -0
  164. data/entry_types/scrolled/package/contentElements-frontend.js +1169 -0
  165. data/entry_types/scrolled/package/editor.js +2930 -371
  166. data/entry_types/scrolled/package/frontend-server.js +228 -0
  167. data/entry_types/scrolled/package/frontend/EditableText-7093fd0e.js +1071 -0
  168. data/entry_types/scrolled/package/frontend/Viewer-e49e7807.js +387 -0
  169. data/entry_types/scrolled/package/frontend/Wavesurfer-0adf5667.js +375 -0
  170. data/entry_types/scrolled/package/frontend/components-6a6793ca.js +2534 -0
  171. data/entry_types/scrolled/package/frontend/getPrototypeOf-63c7c8e8.js +86 -0
  172. data/entry_types/scrolled/package/frontend/i18n-4dc6c377.js +1092 -0
  173. data/entry_types/scrolled/package/frontend/index.css +9 -0
  174. data/entry_types/scrolled/package/frontend/index.js +5686 -0
  175. data/entry_types/scrolled/package/frontend/useBrowserFeature-91a4c29d.js +33 -0
  176. data/entry_types/scrolled/package/package.json +30 -9
  177. data/entry_types/scrolled/spec/fixtures/audio.m4a +0 -0
  178. data/entry_types/scrolled/spec/fixtures/video.mp4 +0 -0
  179. data/lib/generators/pageflow/initializer/templates/pageflow.rb +14 -9
  180. data/lib/pageflow/ability_mixin.rb +14 -2
  181. data/lib/pageflow/configuration.rb +6 -5
  182. data/lib/pageflow/entry_export_import/revision_serialization.rb +15 -13
  183. data/lib/pageflow/entry_export_import/revision_serialization/import.rb +18 -26
  184. data/lib/pageflow/entry_type_configuration.rb +2 -0
  185. data/lib/pageflow/global_config_api.rb +5 -4
  186. data/lib/pageflow/nested_revision_component.rb +49 -0
  187. data/lib/pageflow/react.rb +4 -2
  188. data/lib/pageflow/revision_component.rb +6 -2
  189. data/lib/pageflow/themes.rb +4 -0
  190. data/lib/pageflow/user_mixin.rb +2 -1
  191. data/lib/pageflow/version.rb +1 -1
  192. data/{packages/pageflow → package}/config/jest/index.js +8 -2
  193. data/{packages/pageflow → package}/config/jest/transformers/jst.js +0 -0
  194. data/{packages/pageflow → package}/config/jest/transformers/upwardBabel.js +0 -0
  195. data/{packages/pageflow → package}/config/webpack.js +7 -0
  196. data/{packages/pageflow → package}/editor.js +482 -1130
  197. data/package/frontend.js +2553 -0
  198. data/{packages/pageflow → package}/package.json +3 -0
  199. data/{packages/pageflow → package}/testHelpers.js +114 -13
  200. data/{packages/pageflow → package}/ui.js +178 -55
  201. data/spec/factories/accounts.rb +3 -1
  202. data/spec/factories/entry_templates.rb +1 -0
  203. data/spec/factories/published_entries.rb +6 -1
  204. data/spec/factories/test_revision_components.rb +4 -0
  205. metadata +96 -37
  206. data/app/assets/javascripts/pageflow/dist/editor.js +0 -11890
  207. data/app/assets/javascripts/pageflow/dist/frontend.js +0 -5800
  208. data/app/assets/javascripts/pageflow/videojs.js +0 -6
  209. data/config/initializers/entry_types.rb +0 -4
  210. data/entry_types/scrolled/config/locales/new/de.yml +0 -269
  211. data/entry_types/scrolled/config/locales/new/en.yml +0 -264
  212. data/entry_types/scrolled/lib/tasks/pageflow_scrolled_tasks.rake +0 -96
  213. data/entry_types/scrolled/package/frontend.js +0 -2879
  214. data/packages/pageflow/config/jest/transformers/cssModules.js +0 -1
@@ -0,0 +1,32 @@
1
+ namespace :pageflow_scrolled do
2
+ desc <<-DESC
3
+ Make Yarn use packages embedded in gems.
4
+
5
+ For each package.json dependency of the form
6
+
7
+ .bundle/for-yarn/gem-name/package/path
8
+
9
+ create a symlink in the Git ignored directory .bundle/for-yarn which
10
+ points to the location of the gem as reported by `bundle show`.
11
+
12
+ This script is executed as preinstall script when running `yarn
13
+ install`.
14
+ DESC
15
+ task :create_bundle_symlinks_for_yarn do
16
+ referenced_gems =
17
+ File.read('package.json').scan(%r{.bundle/for-yarn/([a-z_-]+)}).flatten.uniq
18
+
19
+ FileUtils.rm_rf '.bundle/for-yarn'
20
+ FileUtils.mkdir_p '.bundle/for-yarn'
21
+
22
+ puts 'Creating symlinks for .bundle entries in package.json:'
23
+
24
+ referenced_gems.each do |gem|
25
+ symlink = ".bundle/for-yarn/#{gem}"
26
+ gem_location = `bundle show #{gem}`.strip
27
+
28
+ puts "#{symlink} -> #{gem_location}"
29
+ FileUtils.ln_s gem_location, symlink
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ namespace :pageflow_scrolled do
2
+ desc 'Generate dummy app for current Rails version.'
3
+ task :dummy do
4
+ require 'pageflow/support'
5
+ ENV['PAGEFLOW_INSTALL_WEBPACKER'] = 'true'
6
+ Pageflow::Dummy.setup
7
+ end
8
+ end
@@ -0,0 +1,173 @@
1
+ namespace :pageflow_scrolled do
2
+ namespace :storybook do
3
+ namespace :seed do
4
+ desc 'Recreate storybook entry and set up storybook JSON seed/preview-head.html from it'
5
+ task :setup, [:output_dir] => [:destroy_entry, :create_entry,
6
+ :generate_json, :generate_head_html]
7
+
8
+ desc 'Destroy entry to generate Storybook entry JSON seed from'
9
+ task destroy_entry: :environment do
10
+ entry = Pageflow::Entry.find_by_title('Storybook seed')
11
+
12
+ if entry
13
+ puts "Destroying entry 'Storybook seed'"
14
+ entry.destroy
15
+ end
16
+ end
17
+
18
+ desc 'Create entry to generate Storybook entry JSON seed from'
19
+ task create_entry: :environment do
20
+ seeds = Module.new do
21
+ extend Pageflow::Seeds
22
+ extend PageflowScrolled::Seeds
23
+ end
24
+
25
+ if ENV['PAGEFLOW_PAPERCLIP_S3_ROOT']
26
+ Pageflow.config.paperclip_s3_root = ENV['PAGEFLOW_PAPERCLIP_S3_ROOT']
27
+ end
28
+
29
+ if ENV['PAGEFLOW_SCROLLED_DB_SEED_SKIP_FILES'] == 'true'
30
+ puts 'Skipping file uploads to S3.'
31
+ Paperclip::Storage::S3.class_eval { def flush_writes; end }
32
+ end
33
+
34
+ account = seeds.account(name: 'Storybook seed') do |account_in_progress|
35
+ account_in_progress.features_configuration =
36
+ account_in_progress.features_configuration.merge('scrolled_entry_type' => true)
37
+ end
38
+
39
+ seeds.sample_scrolled_entry(
40
+ attributes: {
41
+ title: 'Storybook seed',
42
+ account: account,
43
+ chapters: [],
44
+ image_files: {
45
+ turtle: {
46
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/04_turtle.jpg',
47
+ configuration: {
48
+ focusX: 24,
49
+ focusY: 40,
50
+ testReferenceName: 'turtle'
51
+ }
52
+ }.stringify_keys,
53
+ churchAfter: {
54
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/17_haldern_church_after.jpg',
55
+ configuration: {
56
+ testReferenceName: 'churchAfter'
57
+ }
58
+ }.stringify_keys,
59
+ churchBefore: {
60
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/16_haldern_church_before.jpg',
61
+ configuration: {
62
+ testReferenceName: 'churchBefore'
63
+ }
64
+ }.stringify_keys,
65
+ equirectangularMono: {
66
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/equirectangular_mono.jpg',
67
+ configuration: {
68
+ testReferenceName: 'equirectangularMono',
69
+ projection: 'equirectangular_mono'
70
+ }
71
+ }.stringify_keys,
72
+ equirectangularStereo: {
73
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/equirectangular_stereo.png',
74
+ configuration: {
75
+ testReferenceName: 'equirectangularStereo',
76
+ projection: 'equirectangular_stereo'
77
+ }
78
+ }.stringify_keys
79
+ },
80
+ video_files: {
81
+ interview_toni: {
82
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/videos/08_interview_toni.mp4',
83
+ width: 1920,
84
+ height: 1080,
85
+ configuration: {
86
+ testReferenceName: 'interview_toni'
87
+ }
88
+ }.stringify_keys
89
+ },
90
+ audio_files: {
91
+ quicktime_jingle: {
92
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/audios/quicktime_jingle.m4a',
93
+ configuration: {
94
+ testReferenceName: 'quicktime_jingle'
95
+ }
96
+ }.stringify_keys
97
+ }.stringify_keys,
98
+ text_track_files: {
99
+ sample: {
100
+ url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/text_tracks/sample.vtt',
101
+ parent_file_id: 'quicktime_jingle',
102
+ parent_file_model_type: 'Pageflow::AudioFile'
103
+ }.stringify_keys
104
+ }
105
+ },
106
+ options: {
107
+ skip_encoding: ENV.fetch('PAGEFLOW_SKIP_ENCODING_STORYBOOK_FILES', false)
108
+ }
109
+ )
110
+ end
111
+
112
+ desc 'Generate Storybook entry JSON seed'
113
+ task :generate_json, [:output_dir] => :environment do |_t, args|
114
+ entry = Pageflow::Entry.find_by_title('Storybook seed')
115
+
116
+ unless entry
117
+ puts 'Seed entry does not exist. Run pageflow_scrolled:storybook:seed:create_entry first.'
118
+ exit 1
119
+ end
120
+
121
+ if args[:output_dir].blank?
122
+ puts 'Missing argument: Pass output directory via '\
123
+ '`rake pageflow_scrolled:storybook:seed:setup[some/directory]`'
124
+ exit 1
125
+ end
126
+
127
+ draft_entry = Pageflow::DraftEntry.new(entry)
128
+
129
+ seed =
130
+ I18n.with_locale(draft_entry.locale) do
131
+ PageflowScrolled::EntriesController
132
+ .render(inline: 'scrolled_entry_json_seed(json, entry, ' \
133
+ 'translations: {include_inline_editing: true})',
134
+ type: :jbuilder,
135
+ locals: {entry: draft_entry})
136
+ end
137
+
138
+ output = File.join(args[:output_dir], 'seed.json')
139
+ File.write(output, seed)
140
+ puts "Wrote #{output}"
141
+ end
142
+
143
+ desc 'Generate Storybook preview-head.html'
144
+ task :generate_head_html, [:output_dir] => :environment do |_t, args|
145
+ entry = Pageflow::Entry.find_by_title('Storybook seed')
146
+
147
+ unless entry
148
+ puts 'Seed entry does not exist. Run pageflow_scrolled:storybook:seed:create_entry first.'
149
+ exit 1
150
+ end
151
+
152
+ if args[:output_dir].blank?
153
+ puts 'Missing argument: Pass output directory via '\
154
+ '`rake pageflow_scrolled:storybook:seed:setup[some/directory]`'
155
+ exit 1
156
+ end
157
+
158
+ draft_entry = Pageflow::DraftEntry.new(entry)
159
+
160
+ html =
161
+ File.read(File.join(__dir__, '..', '..', '..', 'package', '.storybook',
162
+ 'preview-head.html.template')) +
163
+ PageflowScrolled::EntriesController.render(inline: <<-ERB, locals: {entry: draft_entry})
164
+ <%= scrolled_theme_properties_style_tag(entry.theme) %>
165
+ ERB
166
+
167
+ output = File.join(args[:output_dir], 'preview-head.html')
168
+ File.write(output, html)
169
+ puts "Wrote #{output}"
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,541 @@
1
+ import { editor, NoOptionsHintView, buttonStyles } from 'pageflow-scrolled/editor';
2
+ import { FileInputView, CheckBoxInputView, ColorInputView as ColorInputView$1, editor as editor$1, transientReferences, ListView, SliderInputView as SliderInputView$1, SelectInputView as SelectInputView$1, EnumTableCellView } from 'pageflow/editor';
3
+ import { SelectInputView, ColorInputView, TextInputView, SliderInputView, CheckBoxInputView as CheckBoxInputView$1, UrlInputView, ConfigurationEditorView, cssModulesUtils } from 'pageflow/ui';
4
+ import Marionette from 'backbone.marionette';
5
+ import I18n from 'i18n-js';
6
+ import Backbone from 'backbone';
7
+ import _ from 'underscore';
8
+
9
+ editor.contentElementTypes.register('heading', {
10
+ supportedPositions: ['inline', 'wide'],
11
+ defaultConfig: {
12
+ position: 'wide'
13
+ },
14
+ configurationEditor: function configurationEditor() {
15
+ this.tab('general', function () {
16
+ this.group('ContentElementPosition');
17
+ });
18
+ }
19
+ });
20
+
21
+ function _defineProperty(obj, key, value) {
22
+ if (key in obj) {
23
+ Object.defineProperty(obj, key, {
24
+ value: value,
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true
28
+ });
29
+ } else {
30
+ obj[key] = value;
31
+ }
32
+
33
+ return obj;
34
+ }
35
+
36
+ function ownKeys(object, enumerableOnly) {
37
+ var keys = Object.keys(object);
38
+
39
+ if (Object.getOwnPropertySymbols) {
40
+ var symbols = Object.getOwnPropertySymbols(object);
41
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
42
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
43
+ });
44
+ keys.push.apply(keys, symbols);
45
+ }
46
+
47
+ return keys;
48
+ }
49
+
50
+ function _objectSpread2(target) {
51
+ for (var i = 1; i < arguments.length; i++) {
52
+ var source = arguments[i] != null ? arguments[i] : {};
53
+
54
+ if (i % 2) {
55
+ ownKeys(Object(source), true).forEach(function (key) {
56
+ _defineProperty(target, key, source[key]);
57
+ });
58
+ } else if (Object.getOwnPropertyDescriptors) {
59
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
60
+ } else {
61
+ ownKeys(Object(source)).forEach(function (key) {
62
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
63
+ });
64
+ }
65
+ }
66
+
67
+ return target;
68
+ }
69
+
70
+ editor.contentElementTypes.register('textBlock', {
71
+ supportedPositions: ['inline'],
72
+ configurationEditor: function configurationEditor() {
73
+ this.tab('general', function () {
74
+ this.view(NoOptionsHintView);
75
+ });
76
+ },
77
+ split: function split(configuration, insertIndex) {
78
+ return [_objectSpread2(_objectSpread2({}, configuration), {}, {
79
+ value: configuration.value.slice(0, insertIndex)
80
+ }), _objectSpread2(_objectSpread2({}, configuration), {}, {
81
+ value: configuration.value.slice(insertIndex)
82
+ })];
83
+ },
84
+ merge: function merge(configurationA, configurationB) {
85
+ // Value might still be empty if text block has not been edited
86
+ var value = (configurationA.value || []).concat(configurationB.value || []);
87
+ return _objectSpread2(_objectSpread2({}, configurationA), {}, {
88
+ // Slate.js does not like empty arrays as value.
89
+ // `inlineEditing/EditableText` sets default value, but only if
90
+ // `value` is falsy.
91
+ value: value.length ? value : undefined
92
+ });
93
+ },
94
+ handleDestroy: function handleDestroy(contentElement) {
95
+ var transientState = contentElement.get('transientState') || {};
96
+
97
+ if (!transientState.editableTextIsSingleBlock) {
98
+ contentElement.postCommand({
99
+ type: 'REMOVE'
100
+ });
101
+ return false;
102
+ }
103
+ }
104
+ });
105
+
106
+ editor.contentElementTypes.register('inlineImage', {
107
+ supportedPositions: ['inline', 'sticky', 'left', 'right', 'wide', 'full'],
108
+ configurationEditor: function configurationEditor() {
109
+ this.tab('general', function () {
110
+ this.input('id', FileInputView, {
111
+ collection: 'image_files',
112
+ fileSelectionHandler: 'contentElementConfiguration',
113
+ positioning: false
114
+ });
115
+ this.group('ContentElementCaption');
116
+ this.group('ContentElementPosition');
117
+ });
118
+ }
119
+ });
120
+
121
+ editor.contentElementTypes.register('inlineVideo', {
122
+ supportedPositions: ['inline', 'sticky', 'left', 'right', 'full'],
123
+ configurationEditor: function configurationEditor() {
124
+ this.tab('general', function () {
125
+ this.input('id', FileInputView, {
126
+ collection: 'video_files',
127
+ fileSelectionHandler: 'contentElementConfiguration',
128
+ positioning: false,
129
+ defaultTextTrackFilePropertyName: 'defaultTextTrackFileId'
130
+ });
131
+ this.input('posterId', FileInputView, {
132
+ collection: 'image_files',
133
+ fileSelectionHandler: 'contentElementConfiguration',
134
+ positioning: false
135
+ });
136
+ this.input('autoplay', CheckBoxInputView);
137
+ this.input('atmoDuringPlayback', SelectInputView, {
138
+ values: ['play', 'mute', 'turnDown']
139
+ });
140
+ this.group('ContentElementCaption');
141
+ this.group('ContentElementPosition');
142
+ });
143
+ }
144
+ });
145
+
146
+ editor.contentElementTypes.register('inlineAudio', {
147
+ supportedPositions: ['inline', 'sticky', 'left', 'right', 'full'],
148
+ configurationEditor: function configurationEditor(_ref) {
149
+ var entry = _ref.entry;
150
+ this.tab('general', function () {
151
+ this.input('id', FileInputView, {
152
+ collection: 'audio_files',
153
+ fileSelectionHandler: 'contentElementConfiguration',
154
+ positioning: false,
155
+ defaultTextTrackFilePropertyName: 'defaultTextTrackFileId'
156
+ });
157
+ this.input('posterId', FileInputView, {
158
+ collection: 'image_files',
159
+ fileSelectionHandler: 'contentElementConfiguration',
160
+ positioning: false
161
+ });
162
+ this.input('autoplay', CheckBoxInputView);
163
+ this.input('playerControlVariant', SelectInputView, {
164
+ values: ['classic', 'waveform'],
165
+ ensureValueDefined: true
166
+ });
167
+ this.input('waveformColor', ColorInputView, {
168
+ visibleBinding: 'playerControlVariant',
169
+ visibleBindingValue: 'waveform',
170
+ defaultValue: entry.getTheme().get('options').colors.accent
171
+ });
172
+ this.input('atmoDuringPlayback', SelectInputView, {
173
+ values: ['play', 'mute', 'turnDown']
174
+ });
175
+ this.group('ContentElementCaption');
176
+ this.group('ContentElementPosition');
177
+ });
178
+ }
179
+ });
180
+
181
+ editor.contentElementTypes.register('inlineBeforeAfter', {
182
+ supportedPositions: ['inline'],
183
+ configurationEditor: function configurationEditor() {
184
+ this.tab('general', function () {
185
+ this.input('before_id', FileInputView, {
186
+ collection: 'image_files',
187
+ fileSelectionHandler: 'contentElementConfiguration',
188
+ positioning: false
189
+ });
190
+ this.input('before_label', TextInputView);
191
+ this.input('after_id', FileInputView, {
192
+ collection: 'image_files',
193
+ fileSelectionHandler: 'contentElementConfiguration',
194
+ positioning: false
195
+ });
196
+ this.input('after_label', TextInputView);
197
+ this.input('initial_slider_position', SliderInputView);
198
+ this.input('slider', CheckBoxInputView$1);
199
+ this.input('slider_handle', CheckBoxInputView$1, {
200
+ visibleBinding: 'slider'
201
+ });
202
+ this.input('slider_color', ColorInputView$1, {
203
+ visibleBinding: 'slider'
204
+ });
205
+ this.group('ContentElementPosition');
206
+ });
207
+ },
208
+ defaultConfig: {
209
+ slider: true,
210
+ slider_handle: true,
211
+ initial_slider_position: 50
212
+ }
213
+ });
214
+
215
+ editor.contentElementTypes.register('soundDisclaimer', {
216
+ supportedPositions: ['inline'],
217
+ configurationEditor: function configurationEditor() {
218
+ this.tab('general', function () {
219
+ this.view(NoOptionsHintView);
220
+ });
221
+ }
222
+ });
223
+
224
+ editor.contentElementTypes.register('videoEmbed', {
225
+ supportedPositions: ['inline', 'sticky', 'left', 'right', 'full'],
226
+ configurationEditor: function configurationEditor() {
227
+ this.tab('general', function () {
228
+ this.input('videoSource', UrlInputView, {
229
+ supportedHosts: ['http://youtu.be', 'https://youtu.be', 'http://www.youtube.com', 'https://www.youtube.com', 'http://vimeo.com', 'https://vimeo.com', 'http://www.facebook.com', 'https://www.facebook.com'],
230
+ displayPropertyName: 'displayVideoSource',
231
+ required: true,
232
+ permitHttps: true
233
+ });
234
+ this.input('hideInfo', CheckBoxInputView$1);
235
+ this.input('hideControls', CheckBoxInputView$1);
236
+ this.input('aspectRatio', SelectInputView, {
237
+ values: ['wide', 'narrow', 'square', 'portrait']
238
+ });
239
+ this.group('ContentElementCaption');
240
+ this.group('ContentElementPosition');
241
+ });
242
+ }
243
+ });
244
+
245
+ var SidebarRouter = Marionette.AppRouter.extend({
246
+ appRoutes: {
247
+ 'scrolled/external_links/:id/:link_id': 'link'
248
+ }
249
+ });
250
+
251
+ var SidebarEditLinkView = Marionette.Layout.extend({
252
+ template: function template(data) {
253
+ return "\n <a class=\"back\">".concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.back'), "</a>\n <a class=\"destroy\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.destroy'), "</a>\n\n <div class='form_container'></div>\n ");
254
+ },
255
+ className: 'edit_external_link',
256
+ regions: {
257
+ formContainer: '.form_container'
258
+ },
259
+ events: {
260
+ 'click a.back': 'goBack',
261
+ 'click a.destroy': 'destroyLink'
262
+ },
263
+ initialize: function initialize(options) {},
264
+ onRender: function onRender() {
265
+ var configurationEditor = new ConfigurationEditorView({
266
+ model: this.model,
267
+ attributeTranslationKeyPrefixes: ['pageflow_scrolled.editor.content_elements.externalLinkList.attributes'],
268
+ tabTranslationKeyPrefix: 'pageflow_scrolled.editor.content_elements.externalLinkList.tabs'
269
+ });
270
+ var self = this;
271
+ configurationEditor.tab('edit_link', function () {
272
+ this.input('url', TextInputView, {
273
+ required: true
274
+ });
275
+ this.input('open_in_new_tab', CheckBoxInputView$1);
276
+ this.input('thumbnail', FileInputView, {
277
+ collection: 'image_files',
278
+ fileSelectionHandler: 'contentElement.externalLinks.link',
279
+ fileSelectionHandlerOptions: {
280
+ contentElementId: self.options.contentElement.get('id')
281
+ },
282
+ positioning: false
283
+ });
284
+ this.input('title', TextInputView, {
285
+ required: true
286
+ });
287
+ this.input('description', TextInputView);
288
+ });
289
+ this.formContainer.show(configurationEditor);
290
+ },
291
+ goBack: function goBack() {
292
+ editor$1.navigate("/scrolled/content_elements/".concat(this.options.contentElement.get('id')), {
293
+ trigger: true
294
+ });
295
+ },
296
+ destroyLink: function destroyLink() {
297
+ if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_link'))) {
298
+ this.options.collection.remove(this.model);
299
+ this.goBack();
300
+ }
301
+ }
302
+ });
303
+
304
+ var ExternalLinkModel = Backbone.Model.extend({
305
+ modelName: 'ExternalLink',
306
+ i18nKey: 'external_link',
307
+ mixins: [transientReferences],
308
+ thumbnailUrl: function thumbnailUrl() {
309
+ var image = this.collection.entry.imageFiles.getByPermaId(this.get('thumbnail'));
310
+ return image ? image.get('thumbnail_url') : '';
311
+ },
312
+ title: function title() {
313
+ return this.get('title');
314
+ }
315
+ });
316
+
317
+ var ExternalLinkCollection = Backbone.Collection.extend({
318
+ model: ExternalLinkModel,
319
+ initialize: function initialize(models, options) {
320
+ this.entry = options.entry;
321
+ this.configuration = options.configuration;
322
+ this.bind('change', this.updateConfiguration);
323
+ this.bind('add', this.updateConfiguration);
324
+ this.bind('remove', this.updateConfiguration);
325
+ },
326
+ modelId: function modelId(attrs) {
327
+ return attrs.id;
328
+ },
329
+ updateConfiguration: function updateConfiguration() {
330
+ this.configuration.set('links', this.toJSON());
331
+ },
332
+ addNewLink: function addNewLink() {
333
+ var newLink = {
334
+ id: this.length + 1,
335
+ title: '',
336
+ url: '',
337
+ thumbnail: '',
338
+ description: '',
339
+ open_in_new_tab: 1
340
+ };
341
+ this.add(newLink);
342
+ return this.get(this.length);
343
+ }
344
+ });
345
+
346
+ ExternalLinkCollection.forContentElement = function (contentElement, entry) {
347
+ return new ExternalLinkCollection(contentElement.configuration.get('links') || [], {
348
+ entry: entry,
349
+ configuration: contentElement.configuration
350
+ });
351
+ };
352
+
353
+ var SidebarController = Marionette.Controller.extend({
354
+ initialize: function initialize(options) {
355
+ this.entry = options.entry;
356
+ this.region = options.region;
357
+ },
358
+ link: function link(id, linkId) {
359
+ var contentElement = this.entry.contentElements.get(id);
360
+ var linksCollection = ExternalLinkCollection.forContentElement(contentElement, this.entry);
361
+ this.region.show(new SidebarEditLinkView({
362
+ model: linksCollection.get(linkId),
363
+ collection: linksCollection,
364
+ contentElement: contentElement
365
+ }));
366
+ }
367
+ });
368
+
369
+ function styleInject(css, ref) {
370
+ if ( ref === void 0 ) ref = {};
371
+ var insertAt = ref.insertAt;
372
+
373
+ if (!css || typeof document === 'undefined') { return; }
374
+
375
+ var head = document.head || document.getElementsByTagName('head')[0];
376
+ var style = document.createElement('style');
377
+ style.type = 'text/css';
378
+
379
+ if (insertAt === 'top') {
380
+ if (head.firstChild) {
381
+ head.insertBefore(style, head.firstChild);
382
+ } else {
383
+ head.appendChild(style);
384
+ }
385
+ } else {
386
+ head.appendChild(style);
387
+ }
388
+
389
+ if (style.styleSheet) {
390
+ style.styleSheet.cssText = css;
391
+ } else {
392
+ style.appendChild(document.createTextNode(css));
393
+ }
394
+ }
395
+
396
+ var css = ".SidebarListView-module_linksContainer__HvWq- {\n}\n";
397
+ var styles = {"linksContainer":"SidebarListView-module_linksContainer__HvWq-"};
398
+ styleInject(css);
399
+
400
+ var SidebarListView = Marionette.Layout.extend({
401
+ template: function template(data) {
402
+ return "\n <div class='".concat(styles.linksContainer, "'></div>\n <button class=\"").concat(buttonStyles.addButton, "\">\n ").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.add'), "\n </button>\n ");
403
+ },
404
+ regions: cssModulesUtils.ui(styles, 'linksContainer'),
405
+ events: cssModulesUtils.events(buttonStyles, {
406
+ 'click addButton': 'addElement'
407
+ }),
408
+ onRender: function onRender() {
409
+ this.linksContainer.show(new ListView({
410
+ collection: this.collection,
411
+ onEdit: _.bind(this.onEdit, this),
412
+ onRemove: _.bind(this.onRemove, this)
413
+ }));
414
+ },
415
+ addElement: function addElement() {
416
+ var newModel = this.collection.addNewLink();
417
+ this.onEdit(newModel);
418
+ },
419
+ onEdit: function onEdit(linkModel) {
420
+ editor.navigate("/scrolled/external_links/".concat(this.options.contentElement.id, "/").concat(linkModel.id), {
421
+ trigger: true
422
+ });
423
+ },
424
+ onRemove: function onRemove(linkModel) {
425
+ if (window.confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_link'))) {
426
+ this.collection.remove(linkModel);
427
+ }
428
+ }
429
+ });
430
+
431
+ //router defines the URL hash path mapping and controller provides functions for the paths
432
+
433
+ editor.registerSideBarRouting({
434
+ router: SidebarRouter,
435
+ controller: SidebarController
436
+ }); // register external link list content element configuration editor for sidebar
437
+
438
+ editor.contentElementTypes.register('externalLinkList', {
439
+ supportedPositions: ['inline'],
440
+ configurationEditor: function configurationEditor(_ref) {
441
+ var entry = _ref.entry;
442
+ this.tab('general', function () {
443
+ this.view(SidebarListView, {
444
+ contentElement: this.model.parent,
445
+ collection: ExternalLinkCollection.forContentElement(this.model.parent, entry)
446
+ });
447
+ });
448
+ }
449
+ }); // register file handler for thumbnail of external link
450
+
451
+ editor.registerFileSelectionHandler('contentElement.externalLinks.link', function (options) {
452
+ var contentElement = options.entry.contentElements.get(options.contentElementId);
453
+ var links = ExternalLinkCollection.forContentElement(contentElement, options.entry);
454
+
455
+ this.call = function (file) {
456
+ var link = links.get(options.id);
457
+ link.setReference('thumbnail', file);
458
+ };
459
+
460
+ this.getReferer = function () {
461
+ return '/scrolled/external_links/' + contentElement.id + '/' + options.id;
462
+ };
463
+ });
464
+
465
+ var DatawrapperAdView = Marionette.ItemView.extend({
466
+ template: function template(data) {
467
+ return "\n <form action=\"https://datawrapper.de/chart/create\" method=\"POST\" target=\"_blank\">\n <input type=\"hidden\" name=\"theme\" value=\"pageflow\" />\n <input type=\"submit\" value=\"".concat(I18n.t('pageflow_scrolled.editor.content_elements.dataWrapperChart.attributes.create_chart.label'), "\" />\n </form>\n ");
468
+ },
469
+ className: 'datawrapper_ad'
470
+ });
471
+
472
+ editor.contentElementTypes.register('dataWrapperChart', {
473
+ supportedPositions: ['inline', 'sticky', 'left', 'right', 'full'],
474
+ configurationEditor: function configurationEditor() {
475
+ this.tab('general', function () {
476
+ this.input('url', UrlInputView, {
477
+ supportedHosts: ['http://cf.datawrapper.de', 'https://cf.datawrapper.de', 'http://datawrapper.dwcdn.de', 'https://datawrapper.dwcdn.de', 'http://datawrapper.dwcdn.net', 'https://datawrapper.dwcdn.net', 'http://charts.datawrapper.de', 'https://charts.datawrapper.de'],
478
+ displayPropertyName: 'displayUrl',
479
+ required: true,
480
+ permitHttps: true
481
+ });
482
+ this.view(DatawrapperAdView);
483
+ this.input('title', TextInputView, {
484
+ placeholder: I18n.t('pageflow_scrolled.public.chart.default_title')
485
+ });
486
+ this.input('backgroundColor', ColorInputView, {
487
+ defaultValue: '#323d4d'
488
+ });
489
+ this.group('ContentElementCaption');
490
+ this.group('ContentElementPosition');
491
+ });
492
+ }
493
+ });
494
+
495
+ editor.contentElementTypes.register('vrImage', {
496
+ configurationEditor: function configurationEditor() {
497
+ this.tab('general', function () {
498
+ this.input('image', FileInputView, {
499
+ collection: 'image_files',
500
+ fileSelectionHandler: 'contentElementConfiguration',
501
+ filter: 'with_projection',
502
+ positioning: false
503
+ });
504
+ this.input('initialYaw', SliderInputView$1, {
505
+ unit: '°',
506
+ minValue: -180,
507
+ maxValue: 180
508
+ });
509
+ this.input('initialPitch', SliderInputView$1, {
510
+ unit: '°',
511
+ minValue: -60,
512
+ maxValue: 60
513
+ });
514
+ this.group('ContentElementCaption');
515
+ this.group('ContentElementPosition');
516
+ });
517
+ }
518
+ });
519
+ editor.fileTypes.modify('image_files', {
520
+ configurationEditorInputs: function configurationEditorInputs(model) {
521
+ var values = ['equirectangular_mono', 'equirectangular_stereo'];
522
+ return [{
523
+ name: 'projection',
524
+ inputView: SelectInputView$1,
525
+ inputViewOptions: {
526
+ includeBlank: true,
527
+ values: values
528
+ }
529
+ }];
530
+ },
531
+ confirmUploadTableColumns: [{
532
+ name: 'projection',
533
+ cellView: EnumTableCellView
534
+ }],
535
+ filters: [{
536
+ name: 'with_projection',
537
+ matches: function matches(file) {
538
+ return !!file.configuration.get('projection');
539
+ }
540
+ }]
541
+ });