pageflow 15.8.0 → 16.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +183 -103
  3. data/README.md +0 -1
  4. data/Rakefile +1 -1
  5. data/admins/pageflow/accounts.rb +12 -16
  6. data/admins/pageflow/entry.rb +28 -26
  7. data/admins/pageflow/entry_templates.rb +5 -7
  8. data/admins/pageflow/sites.rb +53 -0
  9. data/app/assets/javascripts/pageflow/admin/entries.js +16 -7
  10. data/app/assets/javascripts/pageflow/dist/ui.js +298 -72
  11. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +10 -0
  12. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +6 -1
  13. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +4 -0
  14. data/app/assets/stylesheets/pageflow/editor/help.scss +3 -3
  15. data/app/assets/stylesheets/pageflow/editor/info_box.scss +7 -0
  16. data/app/assets/stylesheets/pageflow/editor/inputs/file_input.scss +0 -5
  17. data/app/assets/stylesheets/pageflow/ui/forms.scss +1 -1
  18. data/app/controllers/pageflow/chapters_controller.rb +2 -2
  19. data/app/controllers/pageflow/editor/files_controller.rb +1 -1
  20. data/app/controllers/pageflow/entries_controller.rb +12 -2
  21. data/app/controllers/pageflow/feeds_controller.rb +18 -0
  22. data/app/controllers/pageflow/pages_controller.rb +2 -2
  23. data/app/controllers/pageflow/sitemaps_controller.rb +15 -0
  24. data/app/controllers/pageflow/storylines_controller.rb +2 -2
  25. data/app/helpers/pageflow/common_entry_seed_helper.rb +1 -1
  26. data/app/helpers/pageflow/embed_code_helper.rb +1 -1
  27. data/app/helpers/pageflow/entries_helper.rb +16 -15
  28. data/app/helpers/pageflow/feeds_helper.rb +66 -0
  29. data/app/helpers/pageflow/page_types_helper.rb +9 -9
  30. data/app/helpers/pageflow/sites_helper.rb +11 -0
  31. data/app/helpers/pageflow/social_share_helper.rb +2 -2
  32. data/app/inputs/pageflow_permalink_input.rb +15 -3
  33. data/app/models/concerns/pageflow/reusable_file.rb +3 -3
  34. data/app/models/pageflow/account.rb +13 -31
  35. data/app/models/pageflow/audio_file_url_templates.rb +2 -1
  36. data/app/models/pageflow/{cname_theming_request_scope.rb → cname_site_request_scope.rb} +3 -3
  37. data/app/models/pageflow/customized_theme.rb +1 -1
  38. data/app/models/pageflow/draft_entry.rb +1 -1
  39. data/app/models/pageflow/entries_feed.rb +32 -0
  40. data/app/models/pageflow/entry.rb +3 -4
  41. data/app/models/pageflow/entry_at_revision.rb +2 -2
  42. data/app/models/pageflow/entry_duplicate.rb +1 -1
  43. data/app/models/pageflow/entry_template.rb +4 -4
  44. data/app/models/pageflow/home_button.rb +7 -7
  45. data/app/models/pageflow/image_file.rb +14 -3
  46. data/app/models/pageflow/membership.rb +3 -2
  47. data/app/models/pageflow/other_file.rb +5 -0
  48. data/app/models/pageflow/other_file_url_templates.rb +16 -0
  49. data/app/models/pageflow/permalink.rb +3 -3
  50. data/app/models/pageflow/permalink_directory.rb +2 -2
  51. data/app/models/pageflow/published_entry.rb +8 -2
  52. data/app/models/pageflow/revision.rb +4 -0
  53. data/app/models/pageflow/site.rb +67 -0
  54. data/app/models/pageflow/sitemaps.rb +13 -0
  55. data/app/models/pageflow/theme_customization.rb +1 -1
  56. data/app/models/pageflow/used_file.rb +2 -2
  57. data/app/models/pageflow/video_file_url_templates.rb +3 -1
  58. data/app/models/pageflow/widget.rb +9 -1
  59. data/app/policies/pageflow/account_policy.rb +2 -2
  60. data/app/policies/pageflow/entry_policy.rb +2 -2
  61. data/app/policies/pageflow/entry_template_policy.rb +1 -1
  62. data/app/policies/pageflow/{theming_policy.rb → site_policy.rb} +13 -11
  63. data/app/views/admin/accounts/_entry_template_details.html.arb +1 -1
  64. data/app/views/admin/accounts/_form.html.erb +4 -22
  65. data/app/views/admin/accounts/_site_defaults_inline_help.html.erb +5 -0
  66. data/app/views/admin/entries/_form.html.erb +4 -13
  67. data/app/views/admin/entries/_permalink_inputs.html.erb +2 -3
  68. data/app/views/admin/entries/_site_input.html.erb +15 -0
  69. data/app/views/admin/entries/{entry_type_name_input.html.erb → entry_site_and_type_name_input.html.erb} +3 -0
  70. data/app/views/admin/entry_templates/_form.html.erb +5 -5
  71. data/app/views/admin/sites/_attributes_table.html.arb +12 -0
  72. data/app/views/admin/sites/_fields.html.erb +23 -0
  73. data/app/views/admin/sites/_form.html.erb +5 -0
  74. data/app/views/components/pageflow/admin/entries_tab.rb +1 -2
  75. data/app/views/components/pageflow/admin/entry_templates_tab.rb +10 -11
  76. data/app/views/components/pageflow/admin/extensible_attributes_table.rb +8 -2
  77. data/app/views/components/pageflow/admin/features_tab.rb +1 -1
  78. data/app/views/components/pageflow/admin/sites_tab.rb +35 -0
  79. data/app/views/components/pageflow/admin/users_tab.rb +1 -2
  80. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +1 -0
  81. data/app/views/pageflow/editor/entries/seed.json.erb +1 -1
  82. data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
  83. data/app/views/pageflow/entries/stylesheet.css.erb +1 -1
  84. data/app/views/pageflow/feeds/index.atom.builder +20 -0
  85. data/app/views/pageflow/sitemaps/index.xml.builder +9 -0
  86. data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
  87. data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
  88. data/config/initializers/admin_resource_tabs.rb +29 -12
  89. data/config/initializers/features.rb +1 -0
  90. data/config/initializers/paperclip.rb +4 -0
  91. data/config/locales/de.yml +42 -19
  92. data/config/locales/en.yml +45 -17
  93. data/config/routes.rb +3 -0
  94. data/config/spring.rb +1 -1
  95. data/db/migrate/20221215101134_rename_theming_to_site.rb +9 -0
  96. data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +34 -0
  97. data/db/migrate/20221219203023_add_name_to_sites.rb +5 -0
  98. data/db/migrate/20230103155934_associate_theme_customizations_with_sites.rb +27 -0
  99. data/db/migrate/20230120092923_create_other_files.rb +23 -0
  100. data/db/migrate/20230323115745_add_feeds_enabled_to_sites.rb +5 -0
  101. data/db/migrate/20230323154323_add_sitemap_enabled_to_sites.rb +5 -0
  102. data/db/migrate/20230331103823_add_title_to_sites.rb +5 -0
  103. data/db/migrate/20230405103612_add_custom_feed_url_to_sites.rb +5 -0
  104. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +455 -119
  105. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +31 -8
  106. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +1 -1
  107. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +1 -1
  108. data/entry_types/paged/app/controllers/pageflow_paged/editor/entries_controller.rb +0 -2
  109. data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +1 -0
  110. data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
  111. data/entry_types/paged/config/initializers/features.rb +0 -1
  112. data/entry_types/paged/lib/pageflow_paged/engine.rb +17 -1
  113. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +2 -2
  114. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +3 -4
  115. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +13 -6
  116. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +2 -0
  117. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +11 -0
  118. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +42 -0
  119. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +3 -0
  120. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +31 -10
  121. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +9 -1
  122. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +3 -1
  123. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +23 -0
  124. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +6 -1
  125. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_seed.json.jbuilder +1 -5
  126. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +10 -0
  127. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +44 -41
  128. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_consent_vendors.json.jbuilder +16 -0
  129. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +8 -5
  130. data/entry_types/scrolled/config/initializers/features.rb +5 -0
  131. data/entry_types/scrolled/config/locales/consent_widget.de.yml +4 -0
  132. data/entry_types/scrolled/config/locales/consent_widget.en.yml +4 -0
  133. data/entry_types/scrolled/config/locales/de.yml +189 -8
  134. data/entry_types/scrolled/config/locales/en.yml +207 -2
  135. data/entry_types/scrolled/config/routes.rb +4 -0
  136. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +97 -5
  137. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +1 -1
  138. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +96 -0
  139. data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +38 -0
  140. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +17 -1
  141. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +24 -0
  142. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +6 -1
  143. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +1 -1
  144. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +1 -2
  145. data/entry_types/scrolled/package/contentElements-editor.js +307 -22
  146. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  147. data/entry_types/scrolled/package/contentElements-frontend.js +690 -71
  148. data/entry_types/scrolled/package/editor.js +616 -220
  149. data/entry_types/scrolled/package/frontend/{EditableInlineText.module-c6672f27.js → EditableInlineText.module-fa9e3aff.js} +1669 -1674
  150. data/entry_types/scrolled/package/frontend/PhonePlatformContext-10a1d600.js +32 -0
  151. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-727cce0d.js +107 -0
  152. data/entry_types/scrolled/package/frontend/Viewer-169e14ca.js +154 -0
  153. data/entry_types/scrolled/package/frontend/{Viewer-6b05522f.js → Viewer-ee1aa590.js} +32 -161
  154. data/entry_types/scrolled/package/frontend/arrowRight-92a34ccc.js +77 -0
  155. data/entry_types/scrolled/package/frontend/{components-487daafa.js → components-4a09bfa3.js} +185 -45
  156. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-22e65f92.js → i18n-ddd92820.js} +162 -292
  157. data/entry_types/scrolled/package/frontend/index-02378634.js +118 -0
  158. data/entry_types/scrolled/package/frontend/index.css +1 -1
  159. data/entry_types/scrolled/package/frontend/index.js +375 -40
  160. data/entry_types/scrolled/package/frontend/useContentElementEditorState-63045393.js +52 -0
  161. data/entry_types/scrolled/package/package.json +2 -1
  162. data/entry_types/scrolled/package/testHelpers.js +9 -2
  163. data/entry_types/scrolled/package/values/colors.module.css +15 -0
  164. data/entry_types/scrolled/package/widgets/consentBar.css +1 -0
  165. data/entry_types/scrolled/package/widgets/consentBar.js +426 -0
  166. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  167. data/entry_types/scrolled/package/widgets/defaultNavigation.js +16 -9
  168. data/lib/generators/pageflow/resque/resque_generator.rb +1 -1
  169. data/lib/pageflow/ability_mixin.rb +21 -13
  170. data/lib/pageflow/active_admin_can_can_fix.rb +2 -2
  171. data/lib/pageflow/admin/attributes_table_rows.rb +1 -1
  172. data/lib/pageflow/admin/form_inputs.rb +1 -1
  173. data/lib/pageflow/admin/tabs.rb +1 -1
  174. data/lib/pageflow/built_in_file_type.rb +7 -0
  175. data/lib/pageflow/configuration/permissions.rb +3 -3
  176. data/lib/pageflow/configuration.rb +38 -17
  177. data/lib/pageflow/engine.rb +60 -39
  178. data/lib/pageflow/entry_export_import/entry_serialization.rb +1 -1
  179. data/lib/pageflow/entry_export_import/revision_serialization.rb +1 -1
  180. data/lib/pageflow/file_type.rb +2 -2
  181. data/lib/pageflow/global_config_api.rb +2 -2
  182. data/lib/pageflow/nested_revision_component.rb +23 -5
  183. data/lib/pageflow/primary_domain_entry_redirect.rb +7 -7
  184. data/lib/pageflow/rails_version.rb +19 -0
  185. data/lib/pageflow/seeds.rb +20 -17
  186. data/lib/pageflow/theme_customizations.rb +10 -10
  187. data/lib/pageflow/version.rb +1 -1
  188. data/lib/pageflow/widget_types.rb +4 -0
  189. data/package/config/webpack5.js +14 -0
  190. data/package/editor.js +148 -37
  191. data/package/frontend.js +26 -2
  192. data/package/testHelpers.js +1 -1
  193. data/package/ui.js +296 -71
  194. data/spec/factories/accounts.rb +5 -2
  195. data/spec/factories/draft_entries.rb +2 -2
  196. data/spec/factories/entries.rb +19 -5
  197. data/spec/factories/entry_templates.rb +1 -1
  198. data/spec/factories/permalink_directory.rb +1 -1
  199. data/spec/factories/published_entries.rb +2 -2
  200. data/spec/factories/sites.rb +12 -0
  201. data/vendor/assets/javascripts/iscroll.js +4 -7
  202. metadata +84 -59
  203. data/app/helpers/pageflow/admin/permalinks_helper.rb +0 -15
  204. data/app/helpers/pageflow/themings_helper.rb +0 -11
  205. data/app/models/pageflow/theming.rb +0 -30
  206. data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +0 -5
  207. data/app/views/admin/accounts/_theming_details.html.arb +0 -5
  208. data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -1
  209. data/entry_types/scrolled/package/frontend/arrowRight-7e3d9dd5.js +0 -42
  210. data/spec/factories/themings.rb +0 -7
  211. /data/app/views/pageflow/entries/{_theming.css.erb → _site.css.erb} +0 -0
@@ -0,0 +1,53 @@
1
+ module Pageflow
2
+ ActiveAdmin.register Site, as: 'Site' do
3
+ belongs_to :account
4
+
5
+ menu false
6
+ actions :index, :show, :new, :edit, :create, :update
7
+
8
+ show do
9
+ render 'attributes_table', site: site
10
+
11
+ tabs_view(Pageflow.config.admin_resource_tabs.find_by_resource(site),
12
+ i18n: 'pageflow.admin.resource_tabs',
13
+ authorize: :see_site_admin_tab,
14
+ build_args: [site])
15
+ end
16
+
17
+ form partial: 'form'
18
+
19
+ permit_params do
20
+ [
21
+ :name,
22
+ :title,
23
+ :cname,
24
+ :additional_cnames,
25
+ :feeds_enabled,
26
+ :sitemap_enabled,
27
+ :imprint_link_url,
28
+ :imprint_link_label,
29
+ :copyright_link_url,
30
+ :copyright_link_label,
31
+ :privacy_link_url,
32
+ :home_url
33
+ ] + permitted_admin_form_input_params
34
+ end
35
+
36
+ controller do
37
+ helper Pageflow::Admin::FormHelper
38
+
39
+ def index
40
+ redirect_to admin_account_path(parent, tab: 'sites')
41
+ end
42
+
43
+ private
44
+
45
+ def permitted_admin_form_input_params
46
+ Pageflow
47
+ .config_for(parent)
48
+ .admin_form_inputs
49
+ .permitted_attributes_for(:site)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -88,17 +88,26 @@ jQuery(function($) {
88
88
 
89
89
  $('.admin_entries form.pageflow_entry').each(function() {
90
90
  var accountSelect = $('#entry_account_id', this);
91
- var themingSelect = $('#entry_theming_id', this);
91
+ var siteSelect = $('#entry_site_id', this);
92
92
  var titleInput = $('#entry_title', this);
93
93
 
94
- function updateEntryTypeInput() {
94
+ function updateSiteAndEntryTypeInput() {
95
95
  var selectedAccountId = accountSelect.val();
96
96
 
97
- $.get('/admin/entries/entry_type_name_input' +
97
+ $.get('/admin/entries/entry_site_and_type_name_input' +
98
98
  '?account_id=' + selectedAccountId +
99
99
  '&entry_type_name=' + $('[name="entry[type_name]"]').val())
100
100
  .done(function(response) {
101
- $('#entry_type_name_input').replaceWith(response);
101
+ $('#entry_type_name_input').replaceWith($(response).filter('#entry_type_name_input'));
102
+ $('#entry_site_input').replaceWith($(response).filter('#entry_site_input'));
103
+
104
+ // Set up searchable select
105
+ $(document).trigger('page:load');
106
+
107
+ siteSelect = $('#entry_site_id');
108
+ siteSelect.on('change', updatePermalinkInput);
109
+
110
+ updatePermalinkInput();
102
111
  });
103
112
  }
104
113
 
@@ -119,15 +128,15 @@ jQuery(function($) {
119
128
  function fetchPermalinkInput(callback) {
120
129
  $.get('/admin/entries/permalink_inputs' +
121
130
  '?entry[account_id]=' + accountSelect.val() +
122
- (themingSelect.val() ? '&entry[theming_id]=' + themingSelect.val() : '') +
131
+ (siteSelect.val() ? '&entry[site_id]=' + siteSelect.val() : '') +
123
132
  '&entry[title]=' + encodeURIComponent(titleInput.val()))
124
133
  .done(callback);
125
134
  }
126
135
 
127
- accountSelect.on('change', updateEntryTypeInput);
136
+ accountSelect.on('change', updateSiteAndEntryTypeInput);
128
137
 
129
138
  accountSelect.on('change', updatePermalinkInput);
130
- themingSelect.on('change', updatePermalinkInput);
139
+ siteSelect.on('change', updatePermalinkInput);
131
140
 
132
141
  titleInput.on('change keyup', debounce(updateSlugPlaceholder, 300));
133
142
  });
@@ -1,5 +1,5 @@
1
1
  this.pageflow = this.pageflow || {};
2
- this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, Backbone, ChildViewContainer, IScroll, jquery_minicolors, wysihtml5, Cocktail) {
2
+ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, Backbone, ChildViewContainer, IScroll, jquery_minicolors, wysihtml5, jqueryUi, Cocktail) {
3
3
  'use strict';
4
4
 
5
5
  Marionette = Marionette && Marionette.hasOwnProperty('default') ? Marionette['default'] : Marionette;
@@ -1067,6 +1067,107 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1067
1067
  }
1068
1068
  });
1069
1069
 
1070
+ function _defineProperty(obj, key, value) {
1071
+ if (key in obj) {
1072
+ Object.defineProperty(obj, key, {
1073
+ value: value,
1074
+ enumerable: true,
1075
+ configurable: true,
1076
+ writable: true
1077
+ });
1078
+ } else {
1079
+ obj[key] = value;
1080
+ }
1081
+
1082
+ return obj;
1083
+ }
1084
+
1085
+ function ownKeys(object, enumerableOnly) {
1086
+ var keys = Object.keys(object);
1087
+
1088
+ if (Object.getOwnPropertySymbols) {
1089
+ var symbols = Object.getOwnPropertySymbols(object);
1090
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
1091
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
1092
+ });
1093
+ keys.push.apply(keys, symbols);
1094
+ }
1095
+
1096
+ return keys;
1097
+ }
1098
+
1099
+ function _objectSpread2(target) {
1100
+ for (var i = 1; i < arguments.length; i++) {
1101
+ var source = arguments[i] != null ? arguments[i] : {};
1102
+
1103
+ if (i % 2) {
1104
+ ownKeys(Object(source), true).forEach(function (key) {
1105
+ _defineProperty(target, key, source[key]);
1106
+ });
1107
+ } else if (Object.getOwnPropertyDescriptors) {
1108
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
1109
+ } else {
1110
+ ownKeys(Object(source)).forEach(function (key) {
1111
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
1112
+ });
1113
+ }
1114
+ }
1115
+
1116
+ return target;
1117
+ }
1118
+
1119
+ var attributeBinding = {
1120
+ setupBooleanAttributeBinding: function setupBooleanAttributeBinding(optionName, updateMethod) {
1121
+ this.setupAttributeBinding(optionName, updateMethod, Boolean);
1122
+ },
1123
+ getBooleanAttributBoundOption: function getBooleanAttributBoundOption(optionName) {
1124
+ return this.getAttributeBoundOption(optionName, Boolean);
1125
+ },
1126
+ setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
1127
+ var _this = this;
1128
+
1129
+ var normalize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (value) {
1130
+ return value;
1131
+ };
1132
+ var binding = this.options["".concat(optionName, "Binding")];
1133
+ var view = this;
1134
+
1135
+ if (binding) {
1136
+ _.flatten([binding]).forEach(function (attribute) {
1137
+ _this.listenTo(_this.model, 'change:' + attribute, update);
1138
+ });
1139
+ }
1140
+
1141
+ update();
1142
+
1143
+ function update() {
1144
+ updateMethod.call(view, view.getAttributeBoundOption(optionName, normalize));
1145
+ }
1146
+ },
1147
+ getAttributeBoundOption: function getAttributeBoundOption(optionName) {
1148
+ var _this2 = this;
1149
+
1150
+ var normalize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (value) {
1151
+ return value;
1152
+ };
1153
+ var binding = this.options["".concat(optionName, "Binding")];
1154
+ var bindingValueOptionName = "".concat(optionName, "BindingValue");
1155
+ var value = Array.isArray(binding) ? binding.map(function (attribute) {
1156
+ return _this2.model.get(attribute);
1157
+ }) : this.model.get(binding);
1158
+
1159
+ if (bindingValueOptionName in this.options) {
1160
+ return value === this.options[bindingValueOptionName];
1161
+ } else if (typeof this.options[optionName] === 'function') {
1162
+ return normalize(this.options[optionName](value));
1163
+ } else if (optionName in this.options) {
1164
+ return normalize(this.options[optionName]);
1165
+ } else if (binding) {
1166
+ return normalize(value);
1167
+ }
1168
+ }
1169
+ };
1170
+
1070
1171
  /**
1071
1172
  * Mixin for input views handling common concerns like labels,
1072
1173
  * inline help, visiblity and disabling.
@@ -1196,7 +1297,7 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1196
1297
  * @mixin
1197
1298
  */
1198
1299
 
1199
- var inputView = {
1300
+ var inputView = _objectSpread2(_objectSpread2({}, attributeBinding), {}, {
1200
1301
  ui: {
1201
1302
  label: 'label',
1202
1303
  labelText: 'label .name',
@@ -1240,8 +1341,8 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1240
1341
  this.ui.labelText.text(this.labelText());
1241
1342
  this.updateInlineHelp();
1242
1343
  this.setLabelFor();
1243
- this.setupAttributeBinding('disabled', this.updateDisabled);
1244
- this.setupAttributeBinding('visible', this.updateVisible);
1344
+ this.setupBooleanAttributeBinding('disabled', this.updateDisabled);
1345
+ this.setupBooleanAttributeBinding('visible', this.updateVisible);
1245
1346
  },
1246
1347
 
1247
1348
  /**
@@ -1290,7 +1391,7 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1290
1391
  }
1291
1392
  },
1292
1393
  isDisabled: function isDisabled() {
1293
- return this.getAttributeBoundOption('disabled');
1394
+ return this.getBooleanAttributBoundOption('disabled');
1294
1395
  },
1295
1396
  updateDisabled: function updateDisabled() {
1296
1397
  this.$el.toggleClass('input-disabled', !!this.isDisabled());
@@ -1308,46 +1409,9 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1308
1409
  }
1309
1410
  },
1310
1411
  updateVisible: function updateVisible() {
1311
- this.$el.toggleClass('input-hidden_via_binding', this.getAttributeBoundOption('visible') === false);
1312
- },
1313
- setupAttributeBinding: function setupAttributeBinding(optionName, updateMethod) {
1314
- var _this = this;
1315
-
1316
- var binding = this.options["".concat(optionName, "Binding")];
1317
- var view = this;
1318
-
1319
- if (binding) {
1320
- _.flatten([binding]).forEach(function (attribute) {
1321
- _this.listenTo(_this.model, 'change:' + attribute, update);
1322
- });
1323
- }
1324
-
1325
- update();
1326
-
1327
- function update() {
1328
- updateMethod.call(view, view.getAttributeBoundOption(optionName));
1329
- }
1330
- },
1331
- getAttributeBoundOption: function getAttributeBoundOption(optionName) {
1332
- var _this2 = this;
1333
-
1334
- var binding = this.options["".concat(optionName, "Binding")];
1335
- var bindingValueOptionName = "".concat(optionName, "BindingValue");
1336
- var value = Array.isArray(binding) ? binding.map(function (attribute) {
1337
- return _this2.model.get(attribute);
1338
- }) : this.model.get(binding);
1339
-
1340
- if (bindingValueOptionName in this.options) {
1341
- return value === this.options[bindingValueOptionName];
1342
- } else if (typeof this.options[optionName] === 'function') {
1343
- return !!this.options[optionName](value);
1344
- } else if (optionName in this.options) {
1345
- return !!this.options[optionName];
1346
- } else if (binding) {
1347
- return !!value;
1348
- }
1412
+ this.$el.toggleClass('hidden_via_binding', this.getBooleanAttributBoundOption('visible') === false);
1349
1413
  }
1350
- };
1414
+ });
1351
1415
 
1352
1416
  function template$4(data) {
1353
1417
  var __p = '';
@@ -1466,6 +1530,125 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1466
1530
  }
1467
1531
  });
1468
1532
 
1533
+ function _classCallCheck(instance, Constructor) {
1534
+ if (!(instance instanceof Constructor)) {
1535
+ throw new TypeError("Cannot call a class as a function");
1536
+ }
1537
+ }
1538
+
1539
+ function _defineProperties(target, props) {
1540
+ for (var i = 0; i < props.length; i++) {
1541
+ var descriptor = props[i];
1542
+ descriptor.enumerable = descriptor.enumerable || false;
1543
+ descriptor.configurable = true;
1544
+ if ("value" in descriptor) descriptor.writable = true;
1545
+ Object.defineProperty(target, descriptor.key, descriptor);
1546
+ }
1547
+ }
1548
+
1549
+ function _createClass(Constructor, protoProps, staticProps) {
1550
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
1551
+ if (staticProps) _defineProperties(Constructor, staticProps);
1552
+ return Constructor;
1553
+ }
1554
+
1555
+ /**
1556
+ * Input view for a number.
1557
+ *
1558
+ * See {@link inputView} for further options.
1559
+ *
1560
+ * @param {Object} [options]
1561
+ *
1562
+ * @param {string} [options.locale]
1563
+ * Locale used to fomat and parse numbers.
1564
+ *
1565
+ * @class
1566
+ */
1567
+
1568
+ var NumberInputView = Marionette.ItemView.extend({
1569
+ mixins: [inputView],
1570
+ template: function template() {
1571
+ return "\n <label>\n <span class=\"name\"></span>\n <span class=\"inline_help\"></span>\n </label>\n <input type=\"text\" dir=\"auto\" />\n ";
1572
+ },
1573
+ ui: {
1574
+ input: 'input'
1575
+ },
1576
+ events: {
1577
+ 'change': 'onChange'
1578
+ },
1579
+ initialize: function initialize() {
1580
+ this.parser = new NumberParser(this.options.locale);
1581
+ },
1582
+ onRender: function onRender() {
1583
+ this.load();
1584
+ this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
1585
+ },
1586
+ onChange: function onChange() {
1587
+ this.save();
1588
+ this.load();
1589
+ },
1590
+ onClose: function onClose() {
1591
+ this.save();
1592
+ },
1593
+ save: function save() {
1594
+ var inputValue = this.ui.input.val();
1595
+ this.model.set(this.options.propertyName, this.parser.parse(inputValue) || 0);
1596
+ },
1597
+ load: function load() {
1598
+ var input = this.ui.input;
1599
+ var value = this.model.get(this.options.propertyName) || 0;
1600
+ input.val(value.toLocaleString(this.options.locale, {
1601
+ useGrouping: false
1602
+ }));
1603
+ },
1604
+ displayValidationError: function displayValidationError(message) {
1605
+ this.$el.addClass('invalid');
1606
+ this.ui.input.attr('title', message);
1607
+ },
1608
+ resetValidationError: function resetValidationError(message) {
1609
+ this.$el.removeClass('invalid');
1610
+ this.ui.input.attr('title', '');
1611
+ }
1612
+ });
1613
+
1614
+ var NumberParser = /*#__PURE__*/function () {
1615
+ function NumberParser(locale) {
1616
+ _classCallCheck(this, NumberParser);
1617
+
1618
+ var format = new Intl.NumberFormat(locale);
1619
+ var parts = format.formatToParts(12345.6);
1620
+ var numerals = Array.from({
1621
+ length: 10
1622
+ }).map(function (_, i) {
1623
+ return format.format(i);
1624
+ });
1625
+ var index = new Map(numerals.map(function (d, i) {
1626
+ return [d, i];
1627
+ }));
1628
+ this._group = new RegExp("[".concat(parts.find(function (d) {
1629
+ return d.type === "group";
1630
+ }).value, "]"), "g");
1631
+ this._decimal = new RegExp("[".concat(parts.find(function (d) {
1632
+ return d.type === "decimal";
1633
+ }).value, "]"));
1634
+ this._numeral = new RegExp("[".concat(numerals.join(""), "]"), "g");
1635
+
1636
+ this._index = function (d) {
1637
+ return index.get(d);
1638
+ };
1639
+ }
1640
+
1641
+ _createClass(NumberParser, [{
1642
+ key: "parse",
1643
+ value: function parse(string) {
1644
+ string = string.trim().replace(this._group, "").replace(this._decimal, ".").replace(this._numeral, this._index);
1645
+ return string ? +string : NaN;
1646
+ }
1647
+ }]);
1648
+
1649
+ return NumberParser;
1650
+ }();
1651
+
1469
1652
  /**
1470
1653
  * Text based input view that can display a placeholder.
1471
1654
  *
@@ -1676,11 +1859,15 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1676
1859
  this.ui.input.minicolors({
1677
1860
  changeDelay: 200,
1678
1861
  change: _.bind(function (color) {
1862
+ this._saving = true;
1863
+
1679
1864
  if (color === this.defaultValue()) {
1680
1865
  this.model.unset(this.options.propertyName);
1681
1866
  } else {
1682
1867
  this.model.set(this.options.propertyName, color);
1683
1868
  }
1869
+
1870
+ this._saving = false;
1684
1871
  }, this)
1685
1872
  });
1686
1873
  this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
@@ -1709,7 +1896,10 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
1709
1896
  }
1710
1897
  },
1711
1898
  load: function load() {
1712
- this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
1899
+ if (!this._saving) {
1900
+ this.ui.input.minicolors('value', this.model.get(this.options.propertyName) || this.defaultValue());
1901
+ }
1902
+
1713
1903
  this.$el.toggleClass('is_default', !this.model.has(this.options.propertyName));
1714
1904
  },
1715
1905
  refreshPicker: function refreshPicker() {
@@ -2292,21 +2482,6 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
2292
2482
  }
2293
2483
  });
2294
2484
 
2295
- function _defineProperty(obj, key, value) {
2296
- if (key in obj) {
2297
- Object.defineProperty(obj, key, {
2298
- value: value,
2299
- enumerable: true,
2300
- configurable: true,
2301
- writable: true
2302
- });
2303
- } else {
2304
- obj[key] = value;
2305
- }
2306
-
2307
- return obj;
2308
- }
2309
-
2310
2485
  function template$9(data) {
2311
2486
  var __p = '';
2312
2487
  __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';
@@ -2573,6 +2748,25 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
2573
2748
  *
2574
2749
  * @param {Object} [options]
2575
2750
  *
2751
+ * @param {number} [options.defaultValue]
2752
+ * Defaults value to display if property is not set.
2753
+ *
2754
+ * @param {number} [options.minValue=0]
2755
+ * Value when dragging slider to the very left.
2756
+ *
2757
+ * @param {number} [options.maxValue=100]
2758
+ * Value when dragging slider to the very right.
2759
+ *
2760
+ * @param {string} [options.unit="%"]
2761
+ * Unit to display after value.
2762
+ *
2763
+ * @param {function} [options.displayText]
2764
+ * Function that receives value and returns custom text to display as value.
2765
+ *
2766
+ * @param {boolean} [options.saveOnSlide]
2767
+ * Already update the model while dragging the handle - not only after
2768
+ * handle has been released.
2769
+ *
2576
2770
  * @class
2577
2771
  */
2578
2772
 
@@ -2585,15 +2779,27 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
2585
2779
  value: '.value'
2586
2780
  },
2587
2781
  events: {
2588
- 'slidechange': 'save'
2782
+ 'slidechange': 'save',
2783
+ 'slide': 'handleSlide'
2589
2784
  },
2590
2785
  onRender: function onRender() {
2786
+ var _this = this;
2787
+
2591
2788
  this.ui.widget.slider({
2592
- animate: 'fast',
2593
- min: 'minValue' in this.options ? this.options.minValue : 0,
2594
- max: 'maxValue' in this.options ? this.options.maxValue : 100
2789
+ animate: 'fast'
2790
+ });
2791
+ this.setupAttributeBinding('minValue', function (value) {
2792
+ return _this.updateSliderOption('min', value || 0);
2793
+ });
2794
+ this.setupAttributeBinding('maxValue', function (value) {
2795
+ return _this.updateSliderOption('max', value || 100);
2595
2796
  });
2596
2797
  this.load();
2798
+ this.listenTo(this.model, 'change:' + this.options.propertyName, this.load);
2799
+ },
2800
+ updateSliderOption: function updateSliderOption(name, value) {
2801
+ this.ui.widget.slider('option', name, value);
2802
+ this.updateText(this.ui.widget.slider('value'));
2597
2803
  },
2598
2804
  updateDisabled: function updateDisabled(disabled) {
2599
2805
  this.$el.toggleClass('disabled', !!disabled);
@@ -2604,11 +2810,15 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
2604
2810
  this.ui.widget.slider('enable');
2605
2811
  }
2606
2812
  },
2607
- save: function save() {
2608
- var value = this.ui.widget.slider('option', 'value');
2609
- var unit = 'unit' in this.options ? this.options.unit : '%';
2610
- this.ui.value.text(value + unit);
2611
- this.model.set(this.options.propertyName, value);
2813
+ handleSlide: function handleSlide(event, ui) {
2814
+ this.updateText(ui.value);
2815
+
2816
+ if (this.options.saveOnSlide) {
2817
+ this.save(event, ui);
2818
+ }
2819
+ },
2820
+ save: function save(event, ui) {
2821
+ this.model.set(this.options.propertyName, ui.value);
2612
2822
  },
2613
2823
  load: function load() {
2614
2824
  var value;
@@ -2619,7 +2829,18 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
2619
2829
  value = 'defaultValue' in this.options ? this.options.defaultValue : 0;
2620
2830
  }
2621
2831
 
2622
- this.ui.widget.slider('option', 'value', value);
2832
+ this.ui.widget.slider('option', 'value', this.clampValue(value));
2833
+ this.updateText(value);
2834
+ },
2835
+ clampValue: function clampValue(value) {
2836
+ var min = this.ui.widget.slider('option', 'min');
2837
+ var max = this.ui.widget.slider('option', 'max');
2838
+ return Math.min(max, Math.max(min, value));
2839
+ },
2840
+ updateText: function updateText(value) {
2841
+ var unit = 'unit' in this.options ? this.options.unit : '%';
2842
+ var text = 'displayText' in this.options ? this.options.displayText(value) : value + unit;
2843
+ this.ui.value.text(text);
2623
2844
  }
2624
2845
  });
2625
2846
 
@@ -3013,7 +3234,10 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
3013
3234
  return view;
3014
3235
  },
3015
3236
  appendSubview: function appendSubview(view) {
3016
- return this.$el.append(this.subview(view).el);
3237
+ var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
3238
+ to = _ref.to;
3239
+
3240
+ return (to || this.$el).append(this.subview(view).el);
3017
3241
  },
3018
3242
  onClose: function onClose() {
3019
3243
  if (this.subviews) {
@@ -3082,6 +3306,7 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
3082
3306
  exports.IconTableCellView = IconTableCellView;
3083
3307
  exports.JsonInputView = JsonInputView;
3084
3308
  exports.LabelOnlyView = LabelOnlyView;
3309
+ exports.NumberInputView = NumberInputView;
3085
3310
  exports.Object = BaseObject;
3086
3311
  exports.PresenceTableCellView = PresenceTableCellView;
3087
3312
  exports.ProxyUrlInputView = ProxyUrlInputView;
@@ -3100,6 +3325,7 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
3100
3325
  exports.TooltipView = TooltipView;
3101
3326
  exports.UrlDisplayView = UrlDisplayView;
3102
3327
  exports.UrlInputView = UrlInputView;
3328
+ exports.attributeBinding = attributeBinding;
3103
3329
  exports.cssModulesUtils = cssModulesUtils;
3104
3330
  exports.i18nUtils = i18nUtils;
3105
3331
  exports.inputView = inputView;
@@ -3111,4 +3337,4 @@ this.pageflow._uiGlobalInterop = (function (exports, Marionette, _, $, I18n$1, B
3111
3337
 
3112
3338
  return exports;
3113
3339
 
3114
- }({}, Backbone.Marionette, _, jQuery, I18n, Backbone, Backbone.ChildViewContainer, IScroll, jQuery, wysihtml5, Cocktail));
3340
+ }({}, Backbone.Marionette, _, jQuery, I18n, Backbone, Backbone.ChildViewContainer, IScroll, jQuery, wysihtml5, jQuery, Cocktail));
@@ -62,4 +62,14 @@ $pageflow-permalink-input-directory-background-position: null !default;
62
62
  padding-left: 0;
63
63
  flex: 1;
64
64
  }
65
+
66
+ &.no_directories {
67
+ select {
68
+ display: none;
69
+ }
70
+
71
+ input {
72
+ padding-left: $pageflow-permalink-input-directory-padding-left;
73
+ }
74
+ }
65
75
  }
@@ -10,6 +10,11 @@
10
10
  @include icon-only-button;
11
11
  }
12
12
 
13
+ > button.ellipsis_icon {
14
+ @include fa-ellipsis-v-icon;
15
+ width: 31px;
16
+ }
17
+
13
18
  &.full_width {
14
19
  width: 100%;
15
20
 
@@ -26,7 +31,7 @@
26
31
  @include transition(visibility 100ms, opacity 100ms);
27
32
 
28
33
  position: absolute;
29
- z-index: 1;
34
+ z-index: 6;
30
35
  padding: 1px;
31
36
  border: solid 1px var(--ui-on-surface-color-lighter);
32
37
  border-radius: rounded(sm);
@@ -15,6 +15,10 @@
15
15
  @include note-icon;
16
16
  }
17
17
 
18
+ &.other {
19
+ @include fa-cloud-download-icon;
20
+ }
21
+
18
22
  &.uploading {
19
23
  @include up-bold-icon;
20
24
  }
@@ -162,11 +162,11 @@
162
162
  }
163
163
 
164
164
  .editor .help_button {
165
- @include background-icon-right($color: var(--ui-primary-color),
166
- $font-size: 16px, $right: 5px, $top: 5px);
165
+ @include background-icon-left($color: var(--ui-primary-color),
166
+ $font-size: 16px, $left: 5px, $top: 50%);
167
167
  @include help-circled-icon;
168
168
 
169
- padding: 7px 30px 0 5px;
169
+ padding: 7px 5px 0 28px;
170
170
  float: right;
171
171
  height: 20px;
172
172
  cursor: pointer;
@@ -3,6 +3,13 @@
3
3
  margin-bottom: 1em;
4
4
  }
5
5
 
6
+ &.error {
7
+ color: var(--ui-on-error-surface-color);
8
+ background-color: var(--ui-error-surface-color);
9
+ border-radius: rounded();
10
+ padding: space(3);
11
+ }
12
+
6
13
  .shortcuts {
7
14
  dt {
8
15
  display: block;
@@ -38,11 +38,6 @@
38
38
  }
39
39
 
40
40
  .drop_down_button {
41
- button {
42
- @include fa-ellipsis-v-icon;
43
- width: 31px;
44
- }
45
-
46
41
  position: absolute;
47
42
  bottom: 0;
48
43
  left: 70px;