pageflow 15.1.0 → 15.2.2
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 +92 -161
- data/README.md +1 -2
- data/admins/pageflow/accounts.rb +94 -19
- data/app/assets/javascripts/pageflow/admin/accounts.js +3 -3
- data/app/assets/javascripts/pageflow/dist/frontend.js +2 -0
- data/app/assets/javascripts/pageflow/dist/ui.js +9 -0
- 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/controllers/pageflow/editor/widgets_controller.rb +1 -1
- data/app/helpers/pageflow/pages_helper.rb +1 -0
- data/app/models/pageflow/account.rb +6 -0
- data/app/models/pageflow/draft_entry.rb +13 -3
- data/app/models/pageflow/entry.rb +8 -1
- data/app/models/pageflow/entry_template.rb +55 -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/entry_template_policy.rb +18 -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 +17 -0
- data/app/views/admin/accounts/_form.html.erb +43 -23
- 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/pageflow/themes/_theme.json.jbuilder +1 -0
- data/config/locales/de.yml +12 -7
- data/config/locales/en.yml +12 -7
- 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/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +42 -4
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +1 -0
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +4 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +2 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/i18n_helper.rb +35 -0
- 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 +14 -2
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +10 -1
- data/entry_types/scrolled/config/locales/new/de.yml +231 -8
- data/entry_types/scrolled/config/locales/new/en.yml +228 -10
- data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +3 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +9 -4
- data/entry_types/scrolled/lib/tasks/pageflow_scrolled_tasks.rake +96 -0
- data/entry_types/scrolled/package/contentElements-editor.js +410 -0
- data/entry_types/scrolled/package/contentElements-frontend.js +533 -0
- data/entry_types/scrolled/package/editor.js +498 -2561
- data/entry_types/scrolled/package/frontend.js +713 -1238
- data/entry_types/scrolled/package/package.json +12 -2
- data/lib/pageflow/ability_mixin.rb +3 -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/config/jest/index.js +0 -1
- data/packages/pageflow/config/jest/transformers/jst.js +1 -1
- data/packages/pageflow/config/webpack.js +0 -1
- data/packages/pageflow/editor.js +33 -4
- data/packages/pageflow/package.json +2 -1
- data/packages/pageflow/testHelpers.js +367 -4
- data/packages/pageflow/ui.js +9 -0
- data/spec/factories/accounts.rb +6 -0
- data/spec/factories/entry_templates.rb +8 -0
- data/spec/factories/published_entries.rb +3 -1
- data/spec/factories/themings.rb +0 -1
- metadata +14 -4
- data/app/assets/javascripts/pageflow/dist/editor.js +0 -11881
- data/app/assets/javascripts/pageflow/dist/index.js +0 -3
@@ -21,12 +21,15 @@ module PageflowScrolled
|
|
21
21
|
def editor_pack
|
22
22
|
create_file 'app/javascript/packs/pageflow-scrolled-editor.js', <<-JS
|
23
23
|
import 'pageflow-scrolled/editor';
|
24
|
+
import 'pageflow-scrolled/contentElements-editor';
|
25
|
+
import 'pageflow-scrolled/contentElements-frontend';
|
24
26
|
JS
|
25
27
|
end
|
26
28
|
|
27
29
|
def frontend_pack
|
28
30
|
create_file 'app/javascript/packs/pageflow-scrolled-frontend.js', <<-JS
|
29
31
|
import 'pageflow-scrolled/frontend';
|
32
|
+
import 'pageflow-scrolled/contentElements-frontend';
|
30
33
|
JS
|
31
34
|
end
|
32
35
|
end
|
@@ -102,8 +102,14 @@ module PageflowScrolled
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def create_content_element(section, content_element_config, position, image_files_by_name)
|
105
|
-
if %w[stickyImage inlineImage].include?(
|
106
|
-
|
105
|
+
if %w[stickyImage inlineImage inlineBeforeAfter].include?(
|
106
|
+
content_element_config['type']
|
107
|
+
)
|
108
|
+
rewrite_file_references!(
|
109
|
+
content_element_config['props'],
|
110
|
+
['id', 'before_id', 'after_id'],
|
111
|
+
image_files_by_name
|
112
|
+
)
|
107
113
|
end
|
108
114
|
|
109
115
|
section.content_elements.create!(
|
@@ -126,8 +132,7 @@ module PageflowScrolled
|
|
126
132
|
|
127
133
|
def non_image_reference?(value)
|
128
134
|
value.starts_with?('#') ||
|
129
|
-
value.starts_with?('video')
|
130
|
-
value.starts_with?('beforeAfter')
|
135
|
+
value.starts_with?('video')
|
131
136
|
end
|
132
137
|
end
|
133
138
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
namespace :pageflow_scrolled do
|
2
|
+
desc 'Generate dummy app for current Rails version.'
|
3
|
+
task :dummy do
|
4
|
+
require 'pageflow/support'
|
5
|
+
Pageflow::Dummy.setup
|
6
|
+
end
|
7
|
+
|
8
|
+
namespace :storybook do
|
9
|
+
namespace :seed do
|
10
|
+
task :setup, [:output] => [:destroy_entry, :create_entry, :generate_json]
|
11
|
+
|
12
|
+
desc 'Destroy entry to generate Storybook entry JSON seed from'
|
13
|
+
task destroy_entry: :environment do
|
14
|
+
entry = Pageflow::Entry.find_by_title('Storybook seed')
|
15
|
+
|
16
|
+
if entry
|
17
|
+
puts "Destroying entry 'Storybook seed'"
|
18
|
+
entry.destroy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Create entry to generate Storybook entry JSON seed from'
|
23
|
+
task create_entry: :environment do
|
24
|
+
seeds = Module.new do
|
25
|
+
extend Pageflow::Seeds
|
26
|
+
extend PageflowScrolled::Seeds
|
27
|
+
end
|
28
|
+
|
29
|
+
if ENV['PAGEFLOW_PAPERCLIP_S3_ROOT']
|
30
|
+
Pageflow.config.paperclip_s3_root = ENV['PAGEFLOW_PAPERCLIP_S3_ROOT']
|
31
|
+
end
|
32
|
+
|
33
|
+
if ENV['PAGEFLOW_SCROLLED_DB_SEED_SKIP_FILES'] == 'true'
|
34
|
+
puts 'Skipping file uploads to S3.'
|
35
|
+
Paperclip::Storage::S3.class_eval { def flush_writes; end }
|
36
|
+
end
|
37
|
+
|
38
|
+
account = seeds.account(name: 'Storybook seed')
|
39
|
+
seeds.sample_scrolled_entry(title: 'Storybook seed',
|
40
|
+
account: account,
|
41
|
+
chapters: [],
|
42
|
+
image_files: {
|
43
|
+
turtle: {
|
44
|
+
url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/04_turtle.jpg',
|
45
|
+
configuration: {
|
46
|
+
focusX: 24,
|
47
|
+
focusY: 40,
|
48
|
+
testReferenceName: 'turtle'
|
49
|
+
}
|
50
|
+
}.stringify_keys,
|
51
|
+
churchAfter: {
|
52
|
+
url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/17_haldern_church_after.jpg',
|
53
|
+
configuration: {
|
54
|
+
testReferenceName: 'churchAfter'
|
55
|
+
}
|
56
|
+
}.stringify_keys,
|
57
|
+
churchBefore: {
|
58
|
+
url: 'https://s3-eu-west-1.amazonaws.com/de.codevise.pageflow.development/pageflow-next/seed-assets/images/16_haldern_church_before.jpg',
|
59
|
+
configuration: {
|
60
|
+
testReferenceName: 'churchBefore'
|
61
|
+
}
|
62
|
+
}.stringify_keys
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Generate Storybook entry JSON seed'
|
67
|
+
task :generate_json, [:output] => :environment do |_t, args|
|
68
|
+
entry = Pageflow::Entry.find_by_title('Storybook seed')
|
69
|
+
|
70
|
+
unless entry
|
71
|
+
puts 'Seed entry does not exist. Run pageflow_scrolled:storybook:seed:create_entry first.'
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
|
75
|
+
draft_entry = Pageflow::DraftEntry.new(entry)
|
76
|
+
|
77
|
+
seed =
|
78
|
+
I18n.with_locale(draft_entry.locale) do
|
79
|
+
PageflowScrolled::EntriesController
|
80
|
+
.render(inline: 'scrolled_entry_json_seed(json, entry)',
|
81
|
+
type: :jbuilder,
|
82
|
+
locals: {entry: draft_entry})
|
83
|
+
end
|
84
|
+
|
85
|
+
if args[:output].blank?
|
86
|
+
puts 'Missing argument: Pass output path via '\
|
87
|
+
'`rake pageflow_scrolled:storybook:seed:setup[some/path/seed.json]`'
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
|
91
|
+
File.write(args[:output], seed)
|
92
|
+
puts "Wrote #{args[:output]}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,410 @@
|
|
1
|
+
import { editor as editor$1 } from 'pageflow-scrolled/editor';
|
2
|
+
import { TextInputView, TextAreaInputView, SliderInputView, CheckBoxInputView, UrlInputView, SelectInputView, cssModulesUtils, ConfigurationEditorView } from 'pageflow/ui';
|
3
|
+
import { FileInputView, ColorInputView, ListView, transientReferences } from 'pageflow/editor';
|
4
|
+
import Marionette from 'backbone.marionette';
|
5
|
+
import _ from 'underscore';
|
6
|
+
import Backbone from 'backbone';
|
7
|
+
import I18n$1 from 'i18n-js';
|
8
|
+
|
9
|
+
editor$1.contentElementTypes.register('heading', {
|
10
|
+
configurationEditor: function configurationEditor() {
|
11
|
+
this.tab('general', function () {
|
12
|
+
this.input('children', TextInputView);
|
13
|
+
});
|
14
|
+
}
|
15
|
+
});
|
16
|
+
|
17
|
+
editor$1.contentElementTypes.register('textBlock', {
|
18
|
+
configurationEditor: function configurationEditor() {
|
19
|
+
this.tab('general', function () {
|
20
|
+
this.input('children', TextAreaInputView);
|
21
|
+
});
|
22
|
+
}
|
23
|
+
});
|
24
|
+
|
25
|
+
editor$1.contentElementTypes.register('inlineImage', {
|
26
|
+
configurationEditor: function configurationEditor() {
|
27
|
+
this.tab('general', function () {
|
28
|
+
this.input('id', FileInputView, {
|
29
|
+
collection: 'image_files',
|
30
|
+
fileSelectionHandler: 'contentElementConfiguration'
|
31
|
+
});
|
32
|
+
this.group('ContentElementCaption');
|
33
|
+
this.group('ContentElementPosition');
|
34
|
+
});
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
38
|
+
editor$1.contentElementTypes.register('inlineVideo', {
|
39
|
+
configurationEditor: function configurationEditor() {
|
40
|
+
this.tab('general', function () {});
|
41
|
+
}
|
42
|
+
});
|
43
|
+
|
44
|
+
editor$1.contentElementTypes.register('inlineBeforeAfter', {
|
45
|
+
configurationEditor: function configurationEditor() {
|
46
|
+
this.tab('general', function () {
|
47
|
+
this.input('before_id', FileInputView, {
|
48
|
+
collection: 'image_files',
|
49
|
+
fileSelectionHandler: 'contentElementConfiguration',
|
50
|
+
positioning: false
|
51
|
+
});
|
52
|
+
this.input('before_label', TextInputView);
|
53
|
+
this.input('after_id', FileInputView, {
|
54
|
+
collection: 'image_files',
|
55
|
+
fileSelectionHandler: 'contentElementConfiguration',
|
56
|
+
positioning: false
|
57
|
+
});
|
58
|
+
this.input('after_label', TextInputView);
|
59
|
+
this.input('initial_slider_position', SliderInputView);
|
60
|
+
this.input('slider', CheckBoxInputView);
|
61
|
+
this.input('slider_handle', CheckBoxInputView, {
|
62
|
+
visibleBinding: 'slider'
|
63
|
+
});
|
64
|
+
this.input('slider_color', ColorInputView, {
|
65
|
+
visibleBinding: 'slider'
|
66
|
+
});
|
67
|
+
this.group('ContentElementPosition');
|
68
|
+
});
|
69
|
+
},
|
70
|
+
defaultConfig: {
|
71
|
+
slider: true,
|
72
|
+
slider_handle: true,
|
73
|
+
initial_slider_position: 50
|
74
|
+
}
|
75
|
+
});
|
76
|
+
|
77
|
+
editor$1.contentElementTypes.register('soundDisclaimer', {
|
78
|
+
configurationEditor: function configurationEditor() {
|
79
|
+
this.tab('general', function () {});
|
80
|
+
}
|
81
|
+
});
|
82
|
+
|
83
|
+
editor$1.contentElementTypes.register('videoEmbed', {
|
84
|
+
configurationEditor: function configurationEditor() {
|
85
|
+
this.tab('general', function () {
|
86
|
+
this.input('videoSource', UrlInputView, {
|
87
|
+
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'],
|
88
|
+
displayPropertyName: 'videoSource',
|
89
|
+
required: true,
|
90
|
+
permitHttps: true
|
91
|
+
});
|
92
|
+
this.input('hideInfo', CheckBoxInputView);
|
93
|
+
this.input('hideControls', CheckBoxInputView);
|
94
|
+
this.input('aspectRatio', SelectInputView, {
|
95
|
+
values: ['wide', 'narrow', 'square', 'portrait']
|
96
|
+
});
|
97
|
+
this.group('ContentElementCaption');
|
98
|
+
this.group('ContentElementPosition');
|
99
|
+
});
|
100
|
+
}
|
101
|
+
});
|
102
|
+
|
103
|
+
var SidebarRouter = Marionette.AppRouter.extend({
|
104
|
+
appRoutes: {
|
105
|
+
'scrolled/external_links/:id/': 'links',
|
106
|
+
'scrolled/external_links/:id/:link_id': 'link'
|
107
|
+
}
|
108
|
+
});
|
109
|
+
|
110
|
+
function styleInject(css, ref) {
|
111
|
+
if ( ref === void 0 ) ref = {};
|
112
|
+
var insertAt = ref.insertAt;
|
113
|
+
|
114
|
+
if (!css || typeof document === 'undefined') { return; }
|
115
|
+
|
116
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
117
|
+
var style = document.createElement('style');
|
118
|
+
style.type = 'text/css';
|
119
|
+
|
120
|
+
if (insertAt === 'top') {
|
121
|
+
if (head.firstChild) {
|
122
|
+
head.insertBefore(style, head.firstChild);
|
123
|
+
} else {
|
124
|
+
head.appendChild(style);
|
125
|
+
}
|
126
|
+
} else {
|
127
|
+
head.appendChild(style);
|
128
|
+
}
|
129
|
+
|
130
|
+
if (style.styleSheet) {
|
131
|
+
style.styleSheet.cssText = css;
|
132
|
+
} else {
|
133
|
+
style.appendChild(document.createTextNode(css));
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
var css = ".SidebarListView-module_container__2j0sq {\n margin-top: 30px;\n}\n.SidebarListView-module_add__138Ey{\n border: 1px solid #1c86fe;\n border-radius: 3px;\n box-shadow: inset 0 1px 0 0 #b6d5f8;\n color: white !important;\n display: inline-block;\n font-size: 11px;\n font-weight: bold;\n background-color: #6aacf7;\n background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #6aacf7), color-stop(100%, #2b8efe));\n background-image: -webkit-linear-gradient(#6aacf7, #2b8efe);\n background-image: linear-gradient(#6aacf7, #2b8efe) !important;\n padding: 7px 18px;\n text-decoration: none !important;\n text-shadow: 0 1px 0 #067bff;\n background-clip: padding-box;\n padding-top: 5px;\n padding-bottom: 4px;\n padding-left: 12px\n}\n\n.SidebarListView-module_add__138Ey::before{\n font-family: 'entypo';\n content: \"\\2795\"\n}\n\n.SidebarListView-module_add__138Ey:hover:not(:disabled):not(.SidebarListView-module_disabled__2s_kN) {\n box-shadow: inset 0 1px 0 0 #87baf4;\n cursor: pointer;\n background-color: #559ff2;\n background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #559ff2), color-stop(100%, #1d86fc));\n background-image: -webkit-linear-gradient(#559ff2, #1d86fc);\n background-image: linear-gradient(#559ff2, #1d86fc)\n}\n\n.SidebarListView-module_add__138Ey:active:not(:disabled):not(.SidebarListView-module_disabled__2s_kN) {\n border: 1px solid #1c86fe;\n box-shadow: inset 0 0 8px 4px #0f7efb, inset 0 0 8px 4px #0f7efb, 0 1px 1px 0 #eee\n}\n\n.SidebarListView-module_header__fxwPU{\n display: 'block';\n}\n\n\n.SidebarListView-module_links_container__XDAeC {\n margin-top: 10px;\n}";
|
138
|
+
var styles = {"container":"SidebarListView-module_container__2j0sq","add":"SidebarListView-module_add__138Ey","disabled":"SidebarListView-module_disabled__2s_kN","header":"SidebarListView-module_header__fxwPU","links_container":"SidebarListView-module_links_container__XDAeC"};
|
139
|
+
styleInject(css);
|
140
|
+
|
141
|
+
var SidebarListView = Marionette.Layout.extend({
|
142
|
+
template: function template(data) {
|
143
|
+
return "\n <a class=\"back\">".concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.outline'), "</a>\n <a class=\"destroy\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.destroy'), "</a>\n <div class=\"").concat(styles.container, "\">\n <label class=\"").concat(styles.header, "\">\n <span class=\"name\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.name'), "</span>\n </label>\n <div class='").concat(styles.links_container, "'></div>\n <a class=\"").concat(styles.add, "\" href=\"\">").concat(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.add'), "</a>\n </div>\n ");
|
144
|
+
},
|
145
|
+
className: 'manage_external_links',
|
146
|
+
regions: {
|
147
|
+
linksContainer: '.' + styles.links_container
|
148
|
+
},
|
149
|
+
ui: cssModulesUtils.ui(styles, 'add', 'header'),
|
150
|
+
events: function events() {
|
151
|
+
var eventObject = {
|
152
|
+
'click a.back': 'goBack',
|
153
|
+
'click a.destroy': 'destroyElement'
|
154
|
+
};
|
155
|
+
eventObject['click a.' + styles.add] = 'addElement';
|
156
|
+
return eventObject;
|
157
|
+
},
|
158
|
+
initialize: function initialize(options) {
|
159
|
+
this.listenTo(options.contentElement.configuration, 'change', function () {
|
160
|
+
this.render();
|
161
|
+
});
|
162
|
+
},
|
163
|
+
onRender: function onRender() {
|
164
|
+
this.linksContainer.show(new ListView({
|
165
|
+
collection: this.model,
|
166
|
+
onEdit: _.bind(this.onEdit, this),
|
167
|
+
onRemove: _.bind(this.onRemove, this),
|
168
|
+
contentElement: this.options.contentElement
|
169
|
+
}));
|
170
|
+
},
|
171
|
+
goBack: function goBack() {
|
172
|
+
editor$1.navigate('', {
|
173
|
+
trigger: true
|
174
|
+
});
|
175
|
+
},
|
176
|
+
destroyElement: function destroyElement() {
|
177
|
+
if (confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete'))) {
|
178
|
+
this.options.contentElement.destroy();
|
179
|
+
this.goBack();
|
180
|
+
}
|
181
|
+
},
|
182
|
+
addElement: function addElement() {
|
183
|
+
var newModel = this.model.addNewLink();
|
184
|
+
this.onEdit(newModel);
|
185
|
+
},
|
186
|
+
onEdit: function onEdit(linkModel) {
|
187
|
+
editor$1.navigate("/scrolled/external_links/".concat(this.options.contentElement.get('id'), "/").concat(linkModel.get('id')), {
|
188
|
+
trigger: true
|
189
|
+
});
|
190
|
+
},
|
191
|
+
onRemove: function onRemove(linkModel) {
|
192
|
+
if (confirm(I18n.t('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_link'))) {
|
193
|
+
this.model.remove(linkModel);
|
194
|
+
}
|
195
|
+
}
|
196
|
+
});
|
197
|
+
|
198
|
+
var SidebarEditLinkView = Marionette.Layout.extend({
|
199
|
+
template: function template(data) {
|
200
|
+
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 ");
|
201
|
+
},
|
202
|
+
className: 'edit_external_link',
|
203
|
+
regions: {
|
204
|
+
formContainer: '.form_container'
|
205
|
+
},
|
206
|
+
events: {
|
207
|
+
'click a.back': 'goBack',
|
208
|
+
'click a.destroy': 'destroyLink'
|
209
|
+
},
|
210
|
+
initialize: function initialize(options) {},
|
211
|
+
onRender: function onRender() {
|
212
|
+
var configurationEditor = new ConfigurationEditorView({
|
213
|
+
model: this.model,
|
214
|
+
attributeTranslationKeyPrefixes: ['pageflow_scrolled.editor.content_elements.externalLinkList.attributes'],
|
215
|
+
tabTranslationKeyPrefix: 'pageflow_scrolled.editor.content_elements.externalLinkList.tabs'
|
216
|
+
});
|
217
|
+
var self = this;
|
218
|
+
configurationEditor.tab('edit_link', function () {
|
219
|
+
this.input('url', TextInputView, {
|
220
|
+
required: true
|
221
|
+
});
|
222
|
+
this.input('open_in_new_tab', CheckBoxInputView);
|
223
|
+
this.input('thumbnail', FileInputView, {
|
224
|
+
collection: 'image_files',
|
225
|
+
fileSelectionHandler: 'contentElement.externalLinks.link',
|
226
|
+
fileSelectionHandlerOptions: {
|
227
|
+
contentElementId: self.options.contentElement.get('id')
|
228
|
+
},
|
229
|
+
positioning: false
|
230
|
+
});
|
231
|
+
this.input('title', TextInputView, {
|
232
|
+
required: true
|
233
|
+
});
|
234
|
+
this.input('description', TextAreaInputView, {
|
235
|
+
size: 'short',
|
236
|
+
disableLinks: true
|
237
|
+
});
|
238
|
+
});
|
239
|
+
this.formContainer.show(configurationEditor);
|
240
|
+
},
|
241
|
+
goBack: function goBack() {
|
242
|
+
editor.navigate("/scrolled/external_links/".concat(this.options.contentElement.get('id'), "/"), {
|
243
|
+
trigger: true
|
244
|
+
});
|
245
|
+
},
|
246
|
+
destroyLink: function destroyLink() {
|
247
|
+
if (confirm('pageflow_scrolled.editor.content_elements.externalLinkList.confirm_delete_link')) {
|
248
|
+
this.options.collection.remove(this.model);
|
249
|
+
this.goBack();
|
250
|
+
}
|
251
|
+
}
|
252
|
+
});
|
253
|
+
|
254
|
+
var ExternalLinkModel = Backbone.Model.extend({
|
255
|
+
modelName: 'ExternalLink',
|
256
|
+
i18nKey: 'external_link',
|
257
|
+
mixins: [transientReferences],
|
258
|
+
initialize: function initialize(options) {},
|
259
|
+
thumbnailUrl: function thumbnailUrl() {
|
260
|
+
var image = this.collection.entry.imageFiles.getByPermaId(this.get('thumbnail'));
|
261
|
+
return image ? image.get('thumbnail_url') : '';
|
262
|
+
},
|
263
|
+
title: function title() {
|
264
|
+
return this.get('title');
|
265
|
+
}
|
266
|
+
});
|
267
|
+
|
268
|
+
var ExternalLinkCollection = Backbone.Collection.extend({
|
269
|
+
model: ExternalLinkModel,
|
270
|
+
initialize: function initialize(models, options) {
|
271
|
+
this.entry = options.entry;
|
272
|
+
this.configuration = options.configuration;
|
273
|
+
this.bind('change', this.updateConfiguration);
|
274
|
+
this.bind('add', this.updateConfiguration);
|
275
|
+
this.bind('remove', this.updateConfiguration);
|
276
|
+
},
|
277
|
+
modelId: function modelId(attrs) {
|
278
|
+
return attrs.id;
|
279
|
+
},
|
280
|
+
updateConfiguration: function updateConfiguration() {
|
281
|
+
var _this = this;
|
282
|
+
|
283
|
+
this.configuration.set('links', this.toJSON(), {
|
284
|
+
silent: true
|
285
|
+
});
|
286
|
+
setTimeout(function () {
|
287
|
+
//triggering change event inside this timeout block because otherwise due to
|
288
|
+
//some unknown reason page navigates to window.location.origin+window.location.pathname
|
289
|
+
//ignoring the hash thus causing the page to refresh.
|
290
|
+
_this.configuration.trigger('change');
|
291
|
+
}, 0);
|
292
|
+
},
|
293
|
+
addNewLink: function addNewLink() {
|
294
|
+
var newLink = {
|
295
|
+
id: this.length + 1,
|
296
|
+
title: '',
|
297
|
+
url: '',
|
298
|
+
thumbnail: '',
|
299
|
+
description: '',
|
300
|
+
open_in_new_tab: 1
|
301
|
+
};
|
302
|
+
this.add(newLink);
|
303
|
+
return this.get(this.length);
|
304
|
+
}
|
305
|
+
});
|
306
|
+
|
307
|
+
var SidebarController = Marionette.Controller.extend({
|
308
|
+
initialize: function initialize(options) {
|
309
|
+
this.region = options.region;
|
310
|
+
},
|
311
|
+
links: function links(id) {
|
312
|
+
var _this = this;
|
313
|
+
|
314
|
+
this.setModel(id); //if not done without timeout another empty tab view is shown in the sidebar
|
315
|
+
//to me it seems to be the problem of some method call ordering which gets fixed with this
|
316
|
+
//hack but in future it should be fixed without having to use setTimeout
|
317
|
+
|
318
|
+
setTimeout(function () {
|
319
|
+
_this.region.show(new SidebarListView({
|
320
|
+
model: _this.linksCollection,
|
321
|
+
contentElement: _this.model,
|
322
|
+
entry: _this.options.entry
|
323
|
+
}));
|
324
|
+
}, 0);
|
325
|
+
},
|
326
|
+
link: function link(id, link_id) {
|
327
|
+
var _this2 = this;
|
328
|
+
|
329
|
+
this.setModel(id);
|
330
|
+
setTimeout(function () {
|
331
|
+
_this2.region.show(new SidebarEditLinkView({
|
332
|
+
model: _this2.linksCollection.get(link_id),
|
333
|
+
collection: _this2.linksCollection,
|
334
|
+
contentElement: _this2.model,
|
335
|
+
entry: _this2.options.entry
|
336
|
+
}));
|
337
|
+
}, 0);
|
338
|
+
},
|
339
|
+
setModel: function setModel(id) {
|
340
|
+
this.model = this.options.entry.contentElements.get(id);
|
341
|
+
var configuration = this.model.configuration;
|
342
|
+
|
343
|
+
if (!configuration.get('links')) {
|
344
|
+
configuration.set('links', []);
|
345
|
+
}
|
346
|
+
|
347
|
+
this.linksCollection = new ExternalLinkCollection(configuration.get('links'), {
|
348
|
+
entry: this.options.entry,
|
349
|
+
configuration: configuration
|
350
|
+
});
|
351
|
+
}
|
352
|
+
});
|
353
|
+
|
354
|
+
//router defines the URL hash path mapping and controller provides functions for the paths
|
355
|
+
|
356
|
+
editor$1.registerSideBarRouting({
|
357
|
+
router: SidebarRouter,
|
358
|
+
controller: SidebarController
|
359
|
+
}); // register external link list content element configuration editor for sidebar
|
360
|
+
|
361
|
+
editor$1.contentElementTypes.register('externalLinkList', {
|
362
|
+
configurationEditor: function configurationEditor() {
|
363
|
+
this.tab('general', function () {
|
364
|
+
var externalListModel = this.model.parent; //redirect to special hash path that is specific to external links only
|
365
|
+
|
366
|
+
editor$1.navigate("/scrolled/external_links/".concat(externalListModel.get('id'), "/"), {
|
367
|
+
trigger: true
|
368
|
+
});
|
369
|
+
});
|
370
|
+
}
|
371
|
+
}); // register file handler for thumbnail of external link
|
372
|
+
|
373
|
+
editor$1.registerFileSelectionHandler('contentElement.externalLinks.link', function (options) {
|
374
|
+
var contentElement = options.entry.contentElements.get(options.contentElementId);
|
375
|
+
var links = contentElement.configuration.get('links');
|
376
|
+
|
377
|
+
this.call = function (file) {
|
378
|
+
var link = links.find(function (link) {
|
379
|
+
return link.id == options.id;
|
380
|
+
});
|
381
|
+
link.thumbnail = file.get('perma_id');
|
382
|
+
contentElement.configuration.set('links', links);
|
383
|
+
contentElement.configuration.trigger('change', contentElement.configuration);
|
384
|
+
};
|
385
|
+
|
386
|
+
this.getReferer = function () {
|
387
|
+
return '/scrolled/external_links/' + contentElement.id + '/' + options.id;
|
388
|
+
};
|
389
|
+
});
|
390
|
+
|
391
|
+
var DatawrapperAdView = Marionette.ItemView.extend({
|
392
|
+
template: function template(data) {
|
393
|
+
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$1.t('pageflow_scrolled.editor.content_elements.dataWrapperChart.attributes.create_chart.label'), "\" />\n </form>\n ");
|
394
|
+
},
|
395
|
+
className: 'datawrapper_ad'
|
396
|
+
});
|
397
|
+
|
398
|
+
editor$1.contentElementTypes.register('dataWrapperChart', {
|
399
|
+
configurationEditor: function configurationEditor() {
|
400
|
+
this.tab('general', function () {
|
401
|
+
this.input('url', UrlInputView, {
|
402
|
+
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'],
|
403
|
+
displayPropertyName: 'url',
|
404
|
+
required: true,
|
405
|
+
permitHttps: true
|
406
|
+
});
|
407
|
+
this.view(DatawrapperAdView);
|
408
|
+
});
|
409
|
+
}
|
410
|
+
});
|