pageflow 15.1.1 → 15.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +337 -162
- data/README.md +1 -2
- data/admins/pageflow/accounts.rb +13 -35
- data/admins/pageflow/entry.rb +21 -1
- data/admins/pageflow/entry_templates.rb +140 -0
- data/admins/pageflow/membership.rb +12 -0
- data/admins/pageflow/user.rb +5 -3
- data/app/assets/javascripts/pageflow/admin/accounts.js +3 -3
- data/app/assets/javascripts/pageflow/admin/entries.js +65 -0
- data/app/assets/javascripts/pageflow/admin/users.js +1 -1
- data/app/assets/javascripts/pageflow/asset_urls.js.erb +1 -0
- data/app/assets/javascripts/pageflow/base.js +0 -12
- data/app/assets/javascripts/pageflow/components.js +2 -6
- data/app/assets/javascripts/pageflow/dist/ui.js +56 -14
- data/app/assets/javascripts/pageflow/vendor.js +13 -10
- data/app/assets/stylesheets/pageflow/base.scss +0 -7
- data/app/assets/stylesheets/pageflow/editor/base.scss +2 -0
- data/app/assets/stylesheets/pageflow/editor/composables.scss +5 -1
- data/app/assets/stylesheets/pageflow/editor/emulation_mode_button.scss +44 -55
- data/app/assets/stylesheets/pageflow/editor/help.scss +2 -2
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +4 -0
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +5 -0
- data/app/assets/stylesheets/pageflow/ui/tooltip.scss +17 -3
- data/app/controllers/pageflow/editor/widgets_controller.rb +1 -1
- data/app/helpers/pageflow/admin/entries_helper.rb +16 -0
- data/app/helpers/pageflow/pages_helper.rb +1 -0
- data/app/helpers/pageflow/structured_data_helper.rb +0 -2
- data/app/models/pageflow/account.rb +26 -0
- data/app/models/pageflow/draft_entry.rb +13 -3
- data/app/models/pageflow/entry.rb +16 -2
- data/app/models/pageflow/entry_duplicate.rb +1 -0
- data/app/models/pageflow/entry_template.rb +69 -0
- data/app/models/pageflow/published_entry.rb +13 -3
- data/app/models/pageflow/revision.rb +1 -1
- data/app/models/pageflow/theming.rb +8 -47
- data/app/policies/pageflow/account_policy.rb +10 -0
- data/app/policies/pageflow/entry_template_policy.rb +22 -0
- data/app/policies/pageflow/theming_policy.rb +0 -4
- data/app/views/admin/accounts/_configuration_label.html.erb +5 -0
- data/app/views/admin/accounts/_entry_template_details.html.arb +19 -0
- data/app/views/admin/accounts/_form.html.erb +5 -31
- data/app/views/admin/accounts/_share_providers_label.html.erb +5 -0
- data/app/views/admin/accounts/_theming_details.html.arb +0 -12
- data/app/views/admin/entries/_attributes_table.html.arb +5 -0
- data/app/views/admin/entries/_not_allowed_to_see_entry_types.json.jbuilder +2 -0
- data/app/views/admin/entries/entry_types.json.jbuilder +4 -0
- data/app/views/admin/entry_templates/_form.html.erb +58 -0
- data/app/views/admin/users/_not_allowed_to_see_user_quota.html.erb +3 -0
- data/app/views/components/pageflow/admin/entry_templates_tab.rb +48 -0
- data/app/views/pageflow/admin/users/_quota_exhausted.html.erb +1 -1
- data/app/views/pageflow/themes/_theme.json.jbuilder +1 -0
- data/config/initializers/admin_resource_tabs.rb +5 -0
- data/config/initializers/help_entries.rb +1 -5
- data/config/locales/de.yml +100 -162
- data/config/locales/en.yml +91 -150
- data/db/migrate/20200122115400_create_pageflow_entry_templates.rb +75 -0
- data/db/migrate/20200206134400_convert_legacy_scrolled_content_element_types.rb +48 -0
- data/db/migrate/20200515112500_add_constraints_to_entry_templates.rb +21 -0
- data/db/migrate/20200807135200_rename_pageflow_entry_template_entry_type_to_entry_type_name.rb +7 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/components.js +7 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +1465 -1348
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +9218 -0
- data/{app/assets/javascripts/pageflow → entry_types/paged/app/assets/javascripts/pageflow_paged}/dist/react-client.js +1 -1
- data/{app/assets/javascripts/pageflow → entry_types/paged/app/assets/javascripts/pageflow_paged}/dist/react-server.js +3 -3
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/frontend.js +6 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/server_rendering.js +9 -0
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/vendor.js +8 -0
- data/entry_types/paged/app/controllers/pageflow_paged/application_controller.rb +2 -2
- data/{app/helpers/pageflow → entry_types/paged/app/helpers/pageflow_paged}/page_background_asset_helper.rb +4 -3
- data/{app/helpers/pageflow → entry_types/paged/app/helpers/pageflow_paged}/react_server_side_rendering_helper.rb +23 -2
- data/entry_types/paged/app/views/layouts/pageflow_paged/application.html.erb +2 -2
- data/entry_types/paged/app/views/pageflow_paged/editor/entries/_head.html.erb +2 -2
- data/entry_types/paged/app/views/pageflow_paged/entries/_entry.html.erb +1 -1
- data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/page_background_asset/_element.html.erb +0 -0
- data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/react/_widget.html.erb +0 -0
- data/{app/views/pageflow → entry_types/paged/app/views/pageflow_paged}/react/page.html.erb +0 -0
- data/entry_types/paged/config/initializers/features.rb +1 -1
- data/entry_types/paged/config/initializers/help_entries.rb +17 -0
- data/entry_types/paged/config/locales/new/help.de.yml +162 -0
- data/entry_types/paged/config/locales/new/help.en.yml +153 -0
- data/entry_types/paged/lib/pageflow_paged/engine.rb +13 -0
- data/entry_types/paged/lib/pageflow_paged/plugin.rb +5 -1
- data/entry_types/paged/lib/pageflow_paged/react.rb +12 -0
- data/{lib/pageflow → entry_types/paged/lib/pageflow_paged}/react/page_type.rb +2 -2
- data/{lib/pageflow → entry_types/paged/lib/pageflow_paged}/react/widget_type.rb +2 -2
- data/entry_types/paged/vendor/assets/javascripts/development/pageflow_paged/vendor/react-server.js +20613 -0
- data/entry_types/paged/vendor/assets/javascripts/development/pageflow_paged/vendor/react.js +21495 -0
- data/entry_types/paged/vendor/assets/javascripts/production/pageflow_paged/vendor/react-server.js +24 -0
- data/entry_types/paged/vendor/assets/javascripts/production/pageflow_paged/vendor/react.js +24 -0
- data/entry_types/scrolled/app/assets/javascripts/pageflow_scrolled/legacy.js +0 -0
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +2 -2
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +15 -4
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +2 -2
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +8 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +10 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +4 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +35 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +33 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +8 -0
- data/entry_types/scrolled/app/models/pageflow_scrolled/content_element.rb +38 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/editor/content_elements/batch.json.jbuilder +2 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +1 -7
- data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_seed.json.jbuilder +1 -1
- data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +32 -4
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +13 -1
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_theme.json.jbuilder +7 -0
- data/entry_types/scrolled/config/initializers/help_entries.rb +16 -0
- data/entry_types/scrolled/config/locales/new/de.yml +565 -10
- data/entry_types/scrolled/config/locales/new/en.yml +472 -11
- data/entry_types/scrolled/config/routes.rb +1 -0
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +31 -0
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoDesktop.svg +56 -0
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/templates/theme/logoMobile.svg +22 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +4 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +3 -1
- data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +93 -28
- data/entry_types/scrolled/lib/tasks/pageflow_scrolled_tasks.rake +133 -0
- data/entry_types/scrolled/package/contentElements-editor.js +469 -0
- data/entry_types/scrolled/package/contentElements-frontend.css +1 -0
- data/entry_types/scrolled/package/contentElements-frontend.js +878 -0
- data/entry_types/scrolled/package/editor.js +2725 -2590
- data/entry_types/scrolled/package/frontend-server.js +228 -0
- data/entry_types/scrolled/package/frontend/EditableText-4264c349.js +1993 -0
- data/entry_types/scrolled/package/frontend/Wavesurfer-c3c45324.js +378 -0
- data/entry_types/scrolled/package/frontend/components-cfe6a479.js +2115 -0
- data/entry_types/scrolled/package/frontend/getPrototypeOf-63c7c8e8.js +86 -0
- data/entry_types/scrolled/package/frontend/index.css +9 -0
- data/entry_types/scrolled/package/frontend/index.js +4425 -0
- data/entry_types/scrolled/package/package.json +28 -7
- data/entry_types/scrolled/spec/fixtures/audio.m4a +0 -0
- data/entry_types/scrolled/spec/fixtures/video.mp4 +0 -0
- data/lib/generators/pageflow/initializer/templates/pageflow.rb +20 -9
- data/lib/pageflow/ability_mixin.rb +15 -2
- data/lib/pageflow/configuration.rb +6 -5
- data/lib/pageflow/engine.rb +1 -0
- data/lib/pageflow/entry_type_configuration.rb +1 -0
- data/lib/pageflow/global_config_api.rb +5 -4
- data/lib/pageflow/react.rb +4 -2
- data/lib/pageflow/seeds.rb +0 -2
- data/lib/pageflow/theme.rb +4 -0
- data/lib/pageflow/themes.rb +5 -1
- data/lib/pageflow/version.rb +1 -1
- data/{packages/pageflow → package}/config/jest/index.js +2 -2
- data/{packages/pageflow → package}/config/jest/transformers/jst.js +1 -1
- data/{packages/pageflow → package}/config/jest/transformers/upwardBabel.js +0 -0
- data/package/config/webpack.js +22 -0
- data/{packages/pageflow → package}/editor.js +493 -1122
- data/package/frontend.js +2525 -0
- data/{packages/pageflow → package}/package.json +5 -1
- data/package/testHelpers.js +732 -0
- data/{packages/pageflow → package}/ui.js +56 -14
- data/spec/factories/accounts.rb +9 -1
- data/spec/factories/entry_templates.rb +9 -0
- data/spec/factories/published_entries.rb +8 -1
- data/spec/factories/themings.rb +0 -1
- metadata +74 -27
- data/app/assets/javascripts/pageflow/dist/editor.js +0 -11890
- data/app/assets/javascripts/pageflow/dist/frontend.js +0 -5798
- data/config/initializers/entry_types.rb +0 -4
- data/entry_types/scrolled/package/frontend.js +0 -3404
- data/packages/pageflow/config/jest/transformers/cssModules.js +0 -1
- data/packages/pageflow/config/webpack.js +0 -15
- data/packages/pageflow/testHelpers.js +0 -268
@@ -13,6 +13,7 @@
|
|
13
13
|
"eslint-plugin-import": "^2.18.2",
|
14
14
|
"eslint-plugin-jest": "^23.0.4",
|
15
15
|
"jest": "^24.9.0",
|
16
|
+
"jest-css-modules-processor": "^0.0.9",
|
16
17
|
"jest-jquery-matchers": "^2.1.0",
|
17
18
|
"jest-sinon": "^1.0.0",
|
18
19
|
"sinon": "^7.5.0"
|
@@ -22,6 +23,9 @@
|
|
22
23
|
"lint": "eslint ."
|
23
24
|
},
|
24
25
|
"dependencies": {
|
25
|
-
"
|
26
|
+
"backbone-events-standalone": "^0.2.7",
|
27
|
+
"classlist.js": "^1.1.20150312",
|
28
|
+
"core-js": "^3.4.1",
|
29
|
+
"i18n-js": "^3.5.1"
|
26
30
|
}
|
27
31
|
}
|
@@ -0,0 +1,732 @@
|
|
1
|
+
import $ from 'jquery';
|
2
|
+
import _ from 'underscore';
|
3
|
+
import { Object as Object$1 } from 'pageflow/ui';
|
4
|
+
import Backbone from 'backbone';
|
5
|
+
import { Entry, Theme, FileTypes, FilesCollection, SubsetCollection, ImageFile, WidgetTypes, EditorApi, VideoFile, TextTrackFile } from 'pageflow/editor';
|
6
|
+
import I18n from 'i18n-js';
|
7
|
+
|
8
|
+
var Base = Object$1.extend({
|
9
|
+
initialize: function initialize($el) {
|
10
|
+
this.$el = $el;
|
11
|
+
}
|
12
|
+
});
|
13
|
+
|
14
|
+
Base.classMethods = function (Constructor) {
|
15
|
+
return {
|
16
|
+
find: function find(viewOrParentElement) {
|
17
|
+
var selector = Constructor.prototype.selector;
|
18
|
+
var parentElement = viewOrParentElement.$el || viewOrParentElement;
|
19
|
+
var element = parentElement.find(selector);
|
20
|
+
|
21
|
+
if (element.length > 1) {
|
22
|
+
throw new Error('Selector "' + selector + '" matches multiple elements in view. Expected only one');
|
23
|
+
}
|
24
|
+
|
25
|
+
if (element.length === 0) {
|
26
|
+
throw new Error('Selector "' + selector + '" did not match any elements in view.');
|
27
|
+
}
|
28
|
+
|
29
|
+
return new Constructor(element);
|
30
|
+
},
|
31
|
+
findAll: function findAll(viewOrParentElement) {
|
32
|
+
var selector = Constructor.prototype.selector;
|
33
|
+
var parentElement = viewOrParentElement.$el || viewOrParentElement;
|
34
|
+
var elements = parentElement.find(selector);
|
35
|
+
return elements.map(function () {
|
36
|
+
return new Constructor($(this));
|
37
|
+
}).get();
|
38
|
+
},
|
39
|
+
findBy: function findBy(predicate, options) {
|
40
|
+
var predicateString = options.predicateName ? ' filtered by ' + options.predicateName : '';
|
41
|
+
var selector = Constructor.prototype.selector;
|
42
|
+
var selectorString = 'Selector "' + selector + '"' + predicateString;
|
43
|
+
var elements = options.inView.$el.find(selector);
|
44
|
+
var element = elements.filter(function () {
|
45
|
+
return predicate($(this));
|
46
|
+
});
|
47
|
+
|
48
|
+
if (element.length > 1) {
|
49
|
+
throw new Error(selectorString + ' matches multiple elements in view. Expected only one');
|
50
|
+
}
|
51
|
+
|
52
|
+
if (element.length === 0) {
|
53
|
+
throw new Error(selectorString + ' did not match any elements in view.');
|
54
|
+
}
|
55
|
+
|
56
|
+
return new Constructor(element);
|
57
|
+
},
|
58
|
+
render: function render(view, options) {
|
59
|
+
view.render();
|
60
|
+
|
61
|
+
if (options && options.appendTo) {
|
62
|
+
options.appendTo.append(view.$el);
|
63
|
+
}
|
64
|
+
|
65
|
+
return new Constructor(view.$el);
|
66
|
+
}
|
67
|
+
};
|
68
|
+
};
|
69
|
+
|
70
|
+
Base.extend = function ()
|
71
|
+
/* arguments */
|
72
|
+
{
|
73
|
+
var result = Object$1.extend.apply(this, arguments);
|
74
|
+
|
75
|
+
_.extend(result, Base.classMethods(result));
|
76
|
+
|
77
|
+
return result;
|
78
|
+
};
|
79
|
+
|
80
|
+
var DropDownButton = Base.extend({
|
81
|
+
selector: '.drop_down_button',
|
82
|
+
menuItemNames: function menuItemNames() {
|
83
|
+
return this.$el.find('li').map(function () {
|
84
|
+
return $(this).data('name');
|
85
|
+
}).get();
|
86
|
+
},
|
87
|
+
menuItemLabels: function menuItemLabels() {
|
88
|
+
return this.$el.find('li a').map(function () {
|
89
|
+
return $(this).text();
|
90
|
+
}).get();
|
91
|
+
},
|
92
|
+
selectMenuItemByName: function selectMenuItemByName(name) {
|
93
|
+
var menuItem = this.$el.find('li').filter(function () {
|
94
|
+
return $(this).data('name') == name;
|
95
|
+
});
|
96
|
+
|
97
|
+
if (!menuItem.length) {
|
98
|
+
throw new Error('Could not find menu item with name "' + name + '"');
|
99
|
+
}
|
100
|
+
|
101
|
+
menuItem.find('a').trigger('click');
|
102
|
+
},
|
103
|
+
selectMenuItemByLabel: function selectMenuItemByLabel(label) {
|
104
|
+
var menuItemLink = this.$el.find('li a').filter(function () {
|
105
|
+
return $(this).text() == label;
|
106
|
+
});
|
107
|
+
|
108
|
+
if (!menuItemLink.length) {
|
109
|
+
throw new Error('Could not find menu item with label "' + label + '"');
|
110
|
+
}
|
111
|
+
|
112
|
+
menuItemLink.trigger('click');
|
113
|
+
}
|
114
|
+
});
|
115
|
+
|
116
|
+
var FileMetaDataTable = Base.extend({
|
117
|
+
selector: '.file_meta_data table',
|
118
|
+
values: function values() {
|
119
|
+
return this.$el.find('.value').map(function () {
|
120
|
+
return $(this).text();
|
121
|
+
}).get();
|
122
|
+
}
|
123
|
+
});
|
124
|
+
|
125
|
+
var FileStageItem = Base.extend({
|
126
|
+
selector: '.file_stage_item'
|
127
|
+
});
|
128
|
+
|
129
|
+
var FileThumbnail = Base.extend({
|
130
|
+
selector: '.file_thumbnail',
|
131
|
+
backgroundImage: function backgroundImage() {
|
132
|
+
return this.$el.css('backgroundImage');
|
133
|
+
}
|
134
|
+
});
|
135
|
+
|
136
|
+
var ReferenceInput = Base.extend({
|
137
|
+
clickChooseButton: function clickChooseButton() {
|
138
|
+
this.$el.find('.choose').trigger('click');
|
139
|
+
}
|
140
|
+
});
|
141
|
+
|
142
|
+
var StaticThumbnail = Base.extend({
|
143
|
+
selector: '.static_thumbnail',
|
144
|
+
backgroundImage: function backgroundImage() {
|
145
|
+
return this.$el.css('backgroundImage');
|
146
|
+
}
|
147
|
+
});
|
148
|
+
|
149
|
+
var ThemeItem = Base.extend({
|
150
|
+
selector: '.theme_item',
|
151
|
+
hover: function hover() {
|
152
|
+
this.$el.trigger('mouseenter');
|
153
|
+
},
|
154
|
+
click: function click() {
|
155
|
+
this.$el.trigger('click');
|
156
|
+
},
|
157
|
+
clickUseButton: function clickUseButton() {
|
158
|
+
this.$el.find('.use_theme').trigger('click');
|
159
|
+
}
|
160
|
+
});
|
161
|
+
|
162
|
+
ThemeItem.findByName = function (themeName, options) {
|
163
|
+
return this.findBy(function ($el) {
|
164
|
+
return $el.data('themeName') === themeName;
|
165
|
+
}, _.extend({
|
166
|
+
predicateName: 'theme name ' + themeName
|
167
|
+
}, options));
|
168
|
+
};
|
169
|
+
|
170
|
+
var ConfigurationEditorTab = Base.extend({
|
171
|
+
selector: '.configuration_editor_tab',
|
172
|
+
inputPropertyNames: function inputPropertyNames() {
|
173
|
+
return this.$el.find('.input').map(function () {
|
174
|
+
return $(this).data('inputPropertyName');
|
175
|
+
}).get();
|
176
|
+
},
|
177
|
+
inputLabels: function inputLabels() {
|
178
|
+
return this.$el.find('.input').map(function () {
|
179
|
+
return $(this).data('labelText');
|
180
|
+
}).get();
|
181
|
+
},
|
182
|
+
inlineHelpTexts: function inlineHelpTexts() {
|
183
|
+
return this.$el.find('.input').map(function () {
|
184
|
+
return $(this).data('inlineHelpText');
|
185
|
+
}).get();
|
186
|
+
}
|
187
|
+
});
|
188
|
+
|
189
|
+
var Tabs = Base.extend({
|
190
|
+
selector: '.tabs_view',
|
191
|
+
tabNames: function tabNames() {
|
192
|
+
return this.$el.find('[data-tab-name]').map(function () {
|
193
|
+
return $(this).data('tabName');
|
194
|
+
}).get();
|
195
|
+
},
|
196
|
+
tabLabels: function tabLabels() {
|
197
|
+
return this.$el.find('[data-tab-name]').map(function () {
|
198
|
+
return $(this).text();
|
199
|
+
}).get();
|
200
|
+
}
|
201
|
+
});
|
202
|
+
|
203
|
+
var ConfigurationEditor = Base.extend({
|
204
|
+
selector: '.configuration_editor',
|
205
|
+
tabNames: function tabNames() {
|
206
|
+
return Tabs.find(this.$el).tabNames();
|
207
|
+
},
|
208
|
+
tabLabels: function tabLabels() {
|
209
|
+
return Tabs.find(this.$el).tabLabels();
|
210
|
+
},
|
211
|
+
inputPropertyNames: function inputPropertyNames() {
|
212
|
+
return ConfigurationEditorTab.find(this.$el).inputPropertyNames();
|
213
|
+
},
|
214
|
+
inputLabels: function inputLabels() {
|
215
|
+
return ConfigurationEditorTab.find(this.$el).inputLabels();
|
216
|
+
},
|
217
|
+
inlineHelpTexts: function inlineHelpTexts() {
|
218
|
+
return ConfigurationEditorTab.find(this.$el).inlineHelpTexts();
|
219
|
+
}
|
220
|
+
});
|
221
|
+
|
222
|
+
var Table = Base.extend({
|
223
|
+
selector: '.table_view',
|
224
|
+
columnNames: function columnNames() {
|
225
|
+
return this.$el.find('th').map(function () {
|
226
|
+
return $(this).data('columnName');
|
227
|
+
}).get();
|
228
|
+
}
|
229
|
+
});
|
230
|
+
|
231
|
+
var ColorInput = Base.extend({
|
232
|
+
value: function value() {
|
233
|
+
return this._input().val();
|
234
|
+
},
|
235
|
+
fillIn: function fillIn(value, clock) {
|
236
|
+
this._input().val(value);
|
237
|
+
|
238
|
+
this._input().trigger('keyup');
|
239
|
+
|
240
|
+
clock.tick(500);
|
241
|
+
},
|
242
|
+
swatches: function swatches() {
|
243
|
+
return this.$el.find('.minicolors-swatches span').map(function () {
|
244
|
+
return window.getComputedStyle(this)['background-color'];
|
245
|
+
}).get();
|
246
|
+
},
|
247
|
+
_input: function _input() {
|
248
|
+
return this.$el.find('input');
|
249
|
+
}
|
250
|
+
});
|
251
|
+
|
252
|
+
function _defineProperty(obj, key, value) {
|
253
|
+
if (key in obj) {
|
254
|
+
Object.defineProperty(obj, key, {
|
255
|
+
value: value,
|
256
|
+
enumerable: true,
|
257
|
+
configurable: true,
|
258
|
+
writable: true
|
259
|
+
});
|
260
|
+
} else {
|
261
|
+
obj[key] = value;
|
262
|
+
}
|
263
|
+
|
264
|
+
return obj;
|
265
|
+
}
|
266
|
+
|
267
|
+
function ownKeys(object, enumerableOnly) {
|
268
|
+
var keys = Object.keys(object);
|
269
|
+
|
270
|
+
if (Object.getOwnPropertySymbols) {
|
271
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
272
|
+
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
273
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
274
|
+
});
|
275
|
+
keys.push.apply(keys, symbols);
|
276
|
+
}
|
277
|
+
|
278
|
+
return keys;
|
279
|
+
}
|
280
|
+
|
281
|
+
function _objectSpread2(target) {
|
282
|
+
for (var i = 1; i < arguments.length; i++) {
|
283
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
284
|
+
|
285
|
+
if (i % 2) {
|
286
|
+
ownKeys(Object(source), true).forEach(function (key) {
|
287
|
+
_defineProperty(target, key, source[key]);
|
288
|
+
});
|
289
|
+
} else if (Object.getOwnPropertyDescriptors) {
|
290
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
291
|
+
} else {
|
292
|
+
ownKeys(Object(source)).forEach(function (key) {
|
293
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
294
|
+
});
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
return target;
|
299
|
+
}
|
300
|
+
|
301
|
+
var Base$1 = Base.extend({
|
302
|
+
selector: '.input'
|
303
|
+
});
|
304
|
+
|
305
|
+
Base$1.findByPropertyName = function (propertyName, options) {
|
306
|
+
return this.findBy(function (el) {
|
307
|
+
return el.data('inputPropertyName') === propertyName;
|
308
|
+
}, _objectSpread2({
|
309
|
+
predicateName: "input property name '".concat(propertyName, "'")
|
310
|
+
}, options));
|
311
|
+
};
|
312
|
+
|
313
|
+
var RadioButtonGroupInput = Base$1.extend({
|
314
|
+
values: function values() {
|
315
|
+
return this.$el.find('input').map(function () {
|
316
|
+
return $(this).attr('value');
|
317
|
+
}).get();
|
318
|
+
},
|
319
|
+
enabledValues: function enabledValues() {
|
320
|
+
return this.$el.find('input:not([disabled])').map(function () {
|
321
|
+
return $(this).attr('value');
|
322
|
+
}).get();
|
323
|
+
}
|
324
|
+
});
|
325
|
+
|
326
|
+
var SelectInput = Base$1.extend({
|
327
|
+
value: function value() {
|
328
|
+
return this.$el.find('select').val();
|
329
|
+
},
|
330
|
+
values: function values() {
|
331
|
+
return this.$el.find('option').map(function () {
|
332
|
+
return $(this).attr('value');
|
333
|
+
}).get();
|
334
|
+
},
|
335
|
+
enabledValues: function enabledValues() {
|
336
|
+
return this.$el.find('option:not([disabled])').map(function () {
|
337
|
+
return $(this).attr('value');
|
338
|
+
}).get();
|
339
|
+
}
|
340
|
+
});
|
341
|
+
|
342
|
+
/**
|
343
|
+
* Build editor Backbone models for tests.
|
344
|
+
*/
|
345
|
+
|
346
|
+
var factories = {
|
347
|
+
/**
|
348
|
+
* Build an entry model.
|
349
|
+
*
|
350
|
+
* @param {Function} model - Entry type specific entry model
|
351
|
+
* @param {Object} [attributes] - Model attributes
|
352
|
+
* @param {Object} [options]
|
353
|
+
* @param {Object} [options.entryTypeSeed] - Seed data passed to `Entry#setupFromEntryTypeSeed`.
|
354
|
+
* @param {FileTypes} [options.fileTypes] - Use {@link #factoriesfiletypes factories.fileTypes} to construct this object.
|
355
|
+
* @param {Object} [options.filesAttributes] - An object mapping (underscored) file collection names to arrays of file attributes.
|
356
|
+
* @returns {Entry} - An entry Backbone model.
|
357
|
+
*
|
358
|
+
* @example
|
359
|
+
*
|
360
|
+
* import {factories} from 'pageflow/testHelpers';
|
361
|
+
* import {PagedEntry} from 'editor/models/PagedEntry';
|
362
|
+
*
|
363
|
+
* const entry = factories.entry(PagedEntry, {slug: 'some-entry'}, {
|
364
|
+
* entryTypeSeed: {some: 'data'},
|
365
|
+
* fileTypes: factories.fileTypes(f => f.withImageFileType()),
|
366
|
+
* filesAttributes: {
|
367
|
+
* image_files: [{id: 100, perma_id: 1, basename: 'image'}]
|
368
|
+
* }
|
369
|
+
* });
|
370
|
+
*/
|
371
|
+
entry: function entry(model, attributes) {
|
372
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
373
|
+
|
374
|
+
if (typeof model !== 'function') {
|
375
|
+
return factories.entry(Entry, model, attributes);
|
376
|
+
}
|
377
|
+
|
378
|
+
ensureFileTypes(options);
|
379
|
+
ensureFilesCollections(options);
|
380
|
+
var entry = new model(_objectSpread2({
|
381
|
+
id: 1
|
382
|
+
}, attributes), _.extend({
|
383
|
+
storylines: new Backbone.Collection(),
|
384
|
+
chapters: new Backbone.Collection()
|
385
|
+
}, options));
|
386
|
+
|
387
|
+
if (entry.setupFromEntryTypeSeed && options.entryTypeSeed) {
|
388
|
+
entry.setupFromEntryTypeSeed(options.entryTypeSeed);
|
389
|
+
}
|
390
|
+
|
391
|
+
return entry;
|
392
|
+
},
|
393
|
+
theme: function theme(attributes, options) {
|
394
|
+
return new Theme(attributes, options);
|
395
|
+
},
|
396
|
+
|
397
|
+
/**
|
398
|
+
* Construct a file type registry that can be passed to {@link
|
399
|
+
* #factoriesentry factories.entry}.
|
400
|
+
*
|
401
|
+
* The passed function receives a builder object with the following
|
402
|
+
* methods that register a corresponding file type:
|
403
|
+
*
|
404
|
+
* - `withImageFileType([options])`: Registers a file type with collection name `image_files`.
|
405
|
+
* - `withVideoFileType([options])`: Registers a file type with collection name `video_files`.
|
406
|
+
* - `withTextTrackFileType([options])`: Registers a file type with collection name `text_track_files`.
|
407
|
+
*
|
408
|
+
* @param {Function} fn - Build function.
|
409
|
+
* @returns {FileTypes} - A file Type registry
|
410
|
+
*/
|
411
|
+
fileTypes: function fileTypes(fn) {
|
412
|
+
var fileTypes = new FileTypes();
|
413
|
+
var fileTypesSetupArray = [];
|
414
|
+
var builder = {
|
415
|
+
withImageFileType: function withImageFileType(options) {
|
416
|
+
fileTypes.register('image_files', _.extend({
|
417
|
+
model: ImageFile,
|
418
|
+
matchUpload: /^image/,
|
419
|
+
topLevelType: true
|
420
|
+
}, options));
|
421
|
+
fileTypesSetupArray.push({
|
422
|
+
collectionName: 'image_files',
|
423
|
+
typeName: 'Pageflow::ImageFile',
|
424
|
+
i18nKey: 'pageflow/image_files'
|
425
|
+
});
|
426
|
+
return this;
|
427
|
+
},
|
428
|
+
withVideoFileType: function withVideoFileType(options) {
|
429
|
+
fileTypes.register('video_files', _.extend({
|
430
|
+
model: VideoFile,
|
431
|
+
matchUpload: /^video/,
|
432
|
+
topLevelType: true
|
433
|
+
}, options));
|
434
|
+
fileTypesSetupArray.push({
|
435
|
+
collectionName: 'video_files',
|
436
|
+
typeName: 'Pageflow::VideoFile',
|
437
|
+
i18nKey: 'pageflow/video_files',
|
438
|
+
nestedFileTypes: [{
|
439
|
+
collectionName: 'text_track_files'
|
440
|
+
}]
|
441
|
+
});
|
442
|
+
return this;
|
443
|
+
},
|
444
|
+
withTextTrackFileType: function withTextTrackFileType(options) {
|
445
|
+
fileTypes.register('text_track_files', _.extend({
|
446
|
+
model: TextTrackFile,
|
447
|
+
matchUpload: /vtt$/
|
448
|
+
}, options));
|
449
|
+
fileTypesSetupArray.push({
|
450
|
+
collectionName: 'text_track_files',
|
451
|
+
typeName: 'Pageflow::TextTrackFile',
|
452
|
+
i18nKey: 'pageflow/text_track_files'
|
453
|
+
});
|
454
|
+
return this;
|
455
|
+
}
|
456
|
+
};
|
457
|
+
fn.call(builder, builder);
|
458
|
+
fileTypes.setup(fileTypesSetupArray);
|
459
|
+
return fileTypes;
|
460
|
+
},
|
461
|
+
|
462
|
+
/**
|
463
|
+
* Shorthand for calling {@link #factoriesfiletypes
|
464
|
+
* factories.fileTypes} with a builder function that calls
|
465
|
+
* `withImageFileType`.
|
466
|
+
*
|
467
|
+
* @param {Object} options - File type options passed to withImageFileType,
|
468
|
+
* @returns {FileTypes} - A file Type registry.
|
469
|
+
*/
|
470
|
+
fileTypesWithImageFileType: function fileTypesWithImageFileType(options) {
|
471
|
+
return this.fileTypes(function () {
|
472
|
+
this.withImageFileType(options);
|
473
|
+
});
|
474
|
+
},
|
475
|
+
imageFileType: function imageFileType(options) {
|
476
|
+
return factories.fileTypesWithImageFileType(options).first();
|
477
|
+
},
|
478
|
+
fileType: function fileType(options) {
|
479
|
+
return factories.imageFileType(options);
|
480
|
+
},
|
481
|
+
filesCollection: function filesCollection(options) {
|
482
|
+
return FilesCollection.createForFileType(options.fileType, [{}, {}]);
|
483
|
+
},
|
484
|
+
nestedFilesCollection: function nestedFilesCollection(options) {
|
485
|
+
return new SubsetCollection({
|
486
|
+
parentModel: factories.file({
|
487
|
+
file_name: options.parentFileName
|
488
|
+
}),
|
489
|
+
filter: function filter() {
|
490
|
+
return true;
|
491
|
+
},
|
492
|
+
parent: factories.filesCollection({
|
493
|
+
fileType: options.fileType
|
494
|
+
})
|
495
|
+
});
|
496
|
+
},
|
497
|
+
videoFileWithTextTrackFiles: function videoFileWithTextTrackFiles(options) {
|
498
|
+
var fileTypes = this.fileTypes(function () {
|
499
|
+
this.withVideoFileType(options.videoFileTypeOptions);
|
500
|
+
this.withTextTrackFileType(options.textTrackFileTypeOptions);
|
501
|
+
});
|
502
|
+
var fileAttributes = {
|
503
|
+
video_files: [_.extend({
|
504
|
+
id: 1,
|
505
|
+
state: 'encoded'
|
506
|
+
}, options.videoFileAttributes)],
|
507
|
+
text_track_files: _.map(options.textTrackFilesAttributes, function (attributes) {
|
508
|
+
return _.extend({
|
509
|
+
parent_file_id: 1,
|
510
|
+
parent_file_model_type: 'Pageflow::VideoFile'
|
511
|
+
}, attributes);
|
512
|
+
})
|
513
|
+
};
|
514
|
+
var entry = factories.entry({}, {
|
515
|
+
files: FilesCollection.createForFileTypes(fileTypes, fileAttributes || {}),
|
516
|
+
fileTypes: fileTypes
|
517
|
+
});
|
518
|
+
var videoFiles = entry.getFileCollection(fileTypes.findByCollectionName('video_files'));
|
519
|
+
var textTrackFiles = entry.getFileCollection(fileTypes.findByCollectionName('text_track_files'));
|
520
|
+
return {
|
521
|
+
entry: entry,
|
522
|
+
videoFile: videoFiles.first(),
|
523
|
+
videoFiles: videoFiles,
|
524
|
+
textTrackFiles: textTrackFiles
|
525
|
+
};
|
526
|
+
},
|
527
|
+
imageFilesFixture: function imageFilesFixture(options) {
|
528
|
+
var fileTypes = this.fileTypes(function () {
|
529
|
+
this.withImageFileType(options.fileTypeOptions);
|
530
|
+
});
|
531
|
+
var fileAttributes = {
|
532
|
+
image_files: [_.extend({
|
533
|
+
id: 1,
|
534
|
+
state: 'processed'
|
535
|
+
}, options.imageFileAttributes)]
|
536
|
+
};
|
537
|
+
var entry = factories.entry({}, {
|
538
|
+
files: FilesCollection.createForFileTypes(fileTypes, fileAttributes || {}),
|
539
|
+
fileTypes: fileTypes
|
540
|
+
});
|
541
|
+
var imageFiles = entry.getFileCollection(fileTypes.findByCollectionName('image_files'));
|
542
|
+
return {
|
543
|
+
entry: entry,
|
544
|
+
imageFile: imageFiles.first(),
|
545
|
+
imageFiles: imageFiles
|
546
|
+
};
|
547
|
+
},
|
548
|
+
imageFile: function imageFile(attributes, options) {
|
549
|
+
return new ImageFile(attributes, _.extend({
|
550
|
+
fileType: this.imageFileType()
|
551
|
+
}, options));
|
552
|
+
},
|
553
|
+
file: function file(attributes, options) {
|
554
|
+
return this.imageFile(attributes, options);
|
555
|
+
},
|
556
|
+
widgetTypes: function widgetTypes(attributesList, beforeSetup) {
|
557
|
+
var widgetTypes = new WidgetTypes();
|
558
|
+
var attributesListsByRole = {};
|
559
|
+
|
560
|
+
_(attributesList).each(function (attributes) {
|
561
|
+
attributesListsByRole[attributes.role] = attributesListsByRole[attributes.role] || [];
|
562
|
+
attributesListsByRole[attributes.role].push(_.extend({
|
563
|
+
translationKey: 'widget_name.' + attributes.name
|
564
|
+
}, attributes));
|
565
|
+
});
|
566
|
+
|
567
|
+
if (beforeSetup) {
|
568
|
+
beforeSetup(widgetTypes);
|
569
|
+
}
|
570
|
+
|
571
|
+
widgetTypes.setup(attributesListsByRole);
|
572
|
+
return widgetTypes;
|
573
|
+
},
|
574
|
+
editorApi: function editorApi(beforeSetup) {
|
575
|
+
var api = new EditorApi({
|
576
|
+
router: {
|
577
|
+
navigate: function navigate(path, _ref) {
|
578
|
+
var trigger = _ref.trigger;
|
579
|
+
|
580
|
+
if (trigger) {
|
581
|
+
api.trigger('navigate', path);
|
582
|
+
}
|
583
|
+
}
|
584
|
+
}
|
585
|
+
});
|
586
|
+
|
587
|
+
if (beforeSetup) {
|
588
|
+
beforeSetup(api);
|
589
|
+
}
|
590
|
+
|
591
|
+
api.pageTypes.setup(_.map(api.pageTypes.clientSideConfigs, function (config, name) {
|
592
|
+
return {
|
593
|
+
name: name,
|
594
|
+
translation_key_prefix: 'pageflow.' + name,
|
595
|
+
translation_key: 'pageflow.' + name + '.name',
|
596
|
+
category_translation_key: 'pageflow.' + name + '.category',
|
597
|
+
description_translation_key: 'pageflow.' + name + '.description'
|
598
|
+
};
|
599
|
+
}));
|
600
|
+
return api;
|
601
|
+
}
|
602
|
+
};
|
603
|
+
|
604
|
+
function ensureFileTypes(options) {
|
605
|
+
if (!options.fileTypes) {
|
606
|
+
options.fileTypes = new FileTypes();
|
607
|
+
options.fileTypes.setup([]);
|
608
|
+
}
|
609
|
+
}
|
610
|
+
|
611
|
+
function ensureFilesCollections(options) {
|
612
|
+
if (!options.files) {
|
613
|
+
options.files = FilesCollection.createForFileTypes(options.fileTypes, options.filesAttributes);
|
614
|
+
}
|
615
|
+
}
|
616
|
+
|
617
|
+
var state = window.pageflow || {};
|
618
|
+
|
619
|
+
/**
|
620
|
+
* Setup global state for testing Backbone editro components.
|
621
|
+
*
|
622
|
+
* For some editor components like (some views or models) it's easier
|
623
|
+
* to depend on the global mutable state (available via the `$state`
|
624
|
+
* module alias) instead of injecting dependencies. This helper can be
|
625
|
+
* used to test these components in isolation.
|
626
|
+
*
|
627
|
+
* @param {Object} mapping -
|
628
|
+
* Properties to set on the global state. Functions as values will
|
629
|
+
* be evaluated and the return value will be assigned instead.
|
630
|
+
*/
|
631
|
+
|
632
|
+
var setupGlobals = function setupGlobals(mapping) {
|
633
|
+
var globalsBackup;
|
634
|
+
beforeEach(function () {
|
635
|
+
if (globalsBackup) {
|
636
|
+
throw new Error('There can only be one setupGlobals call per test.');
|
637
|
+
}
|
638
|
+
|
639
|
+
globalsBackup = {};
|
640
|
+
|
641
|
+
_.each(mapping, function (value, key) {
|
642
|
+
globalsBackup[key] = state[key];
|
643
|
+
state[key] = typeof value === 'function' ? value.call(this) : value;
|
644
|
+
});
|
645
|
+
});
|
646
|
+
afterEach(function () {
|
647
|
+
_.each(mapping, function (_, key) {
|
648
|
+
state[key] = globalsBackup[key];
|
649
|
+
});
|
650
|
+
|
651
|
+
globalsBackup = null;
|
652
|
+
});
|
653
|
+
};
|
654
|
+
|
655
|
+
/**
|
656
|
+
* Define translations to use in tests.
|
657
|
+
*
|
658
|
+
* @param {Object} translations -
|
659
|
+
* A mapping of either the form `(translation key => translated
|
660
|
+
* text)`. Translation keys can contains dots.
|
661
|
+
* @param {Object} [options]
|
662
|
+
* @param {boolean} [options.multiLocale] -
|
663
|
+
* Set to `true` if keys include the locale name.
|
664
|
+
*
|
665
|
+
* @example
|
666
|
+
* import {useFakeTranslations} from 'pageflow/testHelpers';
|
667
|
+
* import I18n from 'i18n-js';
|
668
|
+
*
|
669
|
+
* describe('...', () => {
|
670
|
+
* useFakeTranslations({
|
671
|
+
* 'some.key': 'some translation'
|
672
|
+
* });
|
673
|
+
*
|
674
|
+
* it('...', () => {
|
675
|
+
* I18n.t('some.key') // => 'some translation'
|
676
|
+
* });
|
677
|
+
* });
|
678
|
+
*
|
679
|
+
* @example
|
680
|
+
* import {useFakeTranslations} from 'pageflow/testHelpers';
|
681
|
+
* import I18n from 'i18n-js';
|
682
|
+
*
|
683
|
+
* describe('...', () => {
|
684
|
+
* useFakeTranslations({
|
685
|
+
* 'en.some.key': 'some text',
|
686
|
+
* 'de.some.key': 'etwas Text'
|
687
|
+
* }, {multiLocale: true});
|
688
|
+
*
|
689
|
+
* it('...', () => {
|
690
|
+
* I18n.locale = 'de';
|
691
|
+
* I18n.t('some.key') // => 'etwas Text'
|
692
|
+
* });
|
693
|
+
* });
|
694
|
+
*/
|
695
|
+
|
696
|
+
function useFakeTranslations(translations) {
|
697
|
+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
698
|
+
multiLocale = _ref.multiLocale;
|
699
|
+
|
700
|
+
var originalTranslations;
|
701
|
+
beforeEach(function () {
|
702
|
+
originalTranslations = I18n.translations;
|
703
|
+
|
704
|
+
if (multiLocale) {
|
705
|
+
I18n.translations = keysWithDotsToNestedObjects(translations);
|
706
|
+
} else {
|
707
|
+
I18n.translations = {
|
708
|
+
en: keysWithDotsToNestedObjects(translations)
|
709
|
+
};
|
710
|
+
}
|
711
|
+
});
|
712
|
+
afterEach(function () {
|
713
|
+
I18n.translations = originalTranslations;
|
714
|
+
});
|
715
|
+
}
|
716
|
+
|
717
|
+
function keysWithDotsToNestedObjects(translations) {
|
718
|
+
return _(translations).reduce(function (result, value, key) {
|
719
|
+
var keys = key.split('.');
|
720
|
+
var last = keys.pop();
|
721
|
+
|
722
|
+
var inner = _(keys).reduce(function (r, key) {
|
723
|
+
r[key] = r[key] || {};
|
724
|
+
return r[key];
|
725
|
+
}, result);
|
726
|
+
|
727
|
+
inner[last] = value;
|
728
|
+
return result;
|
729
|
+
}, {});
|
730
|
+
}
|
731
|
+
|
732
|
+
export { ColorInput, ConfigurationEditor, ConfigurationEditorTab, DropDownButton, FileMetaDataTable, FileStageItem, FileThumbnail, RadioButtonGroupInput, ReferenceInput, SelectInput, StaticThumbnail, Table, Tabs, ThemeItem, factories, setupGlobals, useFakeTranslations };
|