pageflow 12.0.4 → 12.1.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 +5 -5
- data/CHANGELOG.md +158 -374
- data/README.md +24 -3
- data/Rakefile +2 -2
- data/admins/pageflow/accounts.rb +30 -4
- data/admins/pageflow/entry.rb +59 -9
- data/admins/pageflow/membership.rb +57 -6
- data/admins/pageflow/user.rb +25 -4
- data/app/assets/images/pageflow/themes/default/preview.png +0 -0
- data/app/assets/images/pageflow/themes/default/preview_thumbnail.png +0 -0
- data/app/assets/javascripts/pageflow/admin/entries.js +5 -3
- data/app/assets/javascripts/pageflow/admin/users.js +33 -0
- data/app/assets/javascripts/pageflow/admin.js +4 -1
- data/app/assets/javascripts/pageflow/audio_context.js +28 -0
- data/app/assets/javascripts/pageflow/audio_player/get_media_element_method.js +5 -0
- data/app/assets/javascripts/pageflow/audio_player.js +2 -0
- data/app/assets/javascripts/pageflow/base.js +4 -22
- data/app/assets/javascripts/pageflow/dist/react.js +323 -242
- data/app/assets/javascripts/pageflow/editor/api/widget_type.js +23 -0
- data/app/assets/javascripts/pageflow/editor/api/widget_types.js +53 -0
- data/app/assets/javascripts/pageflow/editor/api.js +9 -1
- data/app/assets/javascripts/pageflow/editor/base.js +0 -1
- data/app/assets/javascripts/pageflow/editor/collections/pages_collection.js +1 -0
- data/app/assets/javascripts/pageflow/editor/collections/subset_collection.js +21 -1
- data/app/assets/javascripts/pageflow/editor/collections/themes_collection.js +13 -0
- data/app/assets/javascripts/pageflow/editor/collections/widgets_collection.js +23 -8
- data/app/assets/javascripts/pageflow/editor/controllers/sidebar_controller.js +7 -1
- data/app/assets/javascripts/pageflow/editor/initializers/setup_collections.js +10 -3
- data/app/assets/javascripts/pageflow/editor/initializers/setup_widget_types.js +5 -1
- data/app/assets/javascripts/pageflow/editor/initializers/stylesheet_reloading.js +8 -3
- data/app/assets/javascripts/pageflow/editor/models/edit_lock_container.js +1 -1
- data/app/assets/javascripts/pageflow/editor/models/entry.js +7 -4
- data/app/assets/javascripts/pageflow/editor/models/entry_configuration.js +1 -1
- data/app/assets/javascripts/pageflow/editor/models/file_stage.js +1 -0
- data/app/assets/javascripts/pageflow/editor/models/page.js +3 -1
- data/app/assets/javascripts/pageflow/editor/models/preview_entry_data.js +2 -2
- data/app/assets/javascripts/pageflow/editor/models/theme.js +25 -0
- data/app/assets/javascripts/pageflow/editor/models/theming.js +1 -19
- data/app/assets/javascripts/pageflow/editor/models/widget.js +22 -1
- data/app/assets/javascripts/pageflow/editor/models/widget_configuration.js +5 -0
- data/app/assets/javascripts/pageflow/editor/routers/sidebar_router.js +1 -0
- data/app/assets/javascripts/pageflow/editor/templates/change_theme_dialog.jst.ejs +23 -0
- data/app/assets/javascripts/pageflow/editor/templates/edit_widget.jst.ejs +1 -2
- data/app/assets/javascripts/pageflow/editor/templates/inputs/reference.jst.ejs +2 -2
- data/app/assets/javascripts/pageflow/editor/templates/static_thumbnail.jst.ejs +1 -0
- data/app/assets/javascripts/pageflow/editor/templates/theme_item.jst.ejs +5 -0
- data/app/assets/javascripts/pageflow/editor/templates/widget_item.jst.ejs +3 -0
- data/app/assets/javascripts/pageflow/editor/utils/stylesheet.js +23 -0
- data/app/assets/javascripts/pageflow/editor/views/change_theme_dialog_view.js +76 -0
- data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/options.js +4 -2
- data/app/assets/javascripts/pageflow/editor/views/edit_meta_data_view.js +17 -4
- data/app/assets/javascripts/pageflow/editor/views/edit_widget_view.js +11 -21
- data/app/assets/javascripts/pageflow/editor/views/edit_widgets_view.js +1 -3
- data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_value_view.js +10 -1
- data/app/assets/javascripts/pageflow/editor/views/inputs/reference_input_view.js +36 -4
- data/app/assets/javascripts/pageflow/editor/views/inputs/theme_input_view.js +26 -0
- data/app/assets/javascripts/pageflow/editor/views/model_thumbnail_view.js +28 -14
- data/app/assets/javascripts/pageflow/editor/views/static_thumbnail_view.js +20 -0
- data/app/assets/javascripts/pageflow/editor/views/theme_item_view.js +41 -0
- data/app/assets/javascripts/pageflow/editor/views/widget_item_view.js +49 -0
- data/app/assets/javascripts/pageflow/history.js +7 -1
- data/app/assets/javascripts/pageflow/media_player/volume_fading/interval.js +65 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading/noop.js +5 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading/web_audio.js +109 -0
- data/app/assets/javascripts/pageflow/media_player/volume_fading.js +14 -65
- data/app/assets/javascripts/pageflow/slideshow/dom_order_scroll_navigator.js +5 -2
- data/app/assets/javascripts/pageflow/slideshow.js +19 -8
- data/app/assets/javascripts/pageflow/ui/views/configuration_editor_view.js +4 -0
- data/app/assets/javascripts/pageflow/ui/views/inputs/text_area_input_view.js +10 -5
- data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +4 -48
- data/app/assets/javascripts/pageflow/ui/views/mixins/input_with_placeholder_text.js +58 -0
- data/app/assets/javascripts/pageflow/vendor.js +16 -0
- data/app/assets/javascripts/pageflow/video_player/get_media_element_method.js +6 -0
- data/app/assets/javascripts/pageflow/video_player.js +2 -0
- data/app/assets/stylesheets/pageflow/admin/entries.scss +1 -1
- data/app/assets/stylesheets/pageflow/admin/quotas.scss +1 -1
- data/app/assets/stylesheets/pageflow/admin.scss +2 -0
- data/app/assets/stylesheets/pageflow/base.scss +0 -1
- data/app/assets/stylesheets/pageflow/editor/base.scss +2 -0
- data/app/assets/stylesheets/pageflow/editor/change_theme.scss +114 -0
- data/app/assets/stylesheets/pageflow/editor/static_thumbnails.scss +4 -0
- data/app/assets/stylesheets/pageflow/editor/widgets.scss +26 -2
- data/app/assets/stylesheets/pageflow/page.scss +1 -14
- data/app/assets/stylesheets/pageflow/themes/default/indicators.scss +12 -0
- data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +11 -0
- data/app/assets/stylesheets/pageflow/themes/default/logo/alignment.scss +27 -0
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +20 -2
- data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +4 -1
- data/app/assets/stylesheets/pageflow/themes/default/page/line_lengths.scss +113 -0
- data/app/assets/stylesheets/pageflow/themes/default/page.scss +1 -0
- data/app/controllers/pageflow/editor/widgets_controller.rb +15 -1
- data/app/controllers/pageflow/entries_controller.rb +1 -1
- data/app/helpers/pageflow/admin/entries_helper.rb +0 -9
- data/app/helpers/pageflow/admin/memberships_helper.rb +43 -123
- data/app/helpers/pageflow/admin/users_helper.rb +15 -0
- data/app/helpers/pageflow/entries_helper.rb +3 -1
- data/app/helpers/pageflow/entry_json_seed_helper.rb +9 -3
- data/app/helpers/pageflow/public_i18n_helper.rb +2 -2
- data/app/helpers/pageflow/quota_helper.rb +2 -2
- data/app/helpers/pageflow/social_share_helper.rb +3 -2
- data/app/helpers/pageflow/themes_helper.rb +11 -3
- data/app/helpers/pageflow/widgets_helper.rb +10 -2
- data/app/jobs/pageflow/prune_auto_snapshots_job.rb +9 -0
- data/app/mailers/pageflow/user_mailer.rb +11 -1
- data/app/models/concerns/pageflow/feature_target.rb +1 -1
- data/app/models/concerns/pageflow/hosted_file.rb +9 -0
- data/app/models/concerns/pageflow/output_source.rb +2 -1
- data/app/models/concerns/pageflow/serialization_blacklist.rb +19 -0
- data/app/models/concerns/pageflow/serialized_configuration.rb +17 -0
- data/app/models/concerns/pageflow/theme_referencer.rb +23 -0
- data/app/models/pageflow/account.rb +6 -1
- data/app/models/pageflow/account_member_query.rb +6 -12
- data/app/models/pageflow/account_role_query.rb +68 -0
- data/app/models/pageflow/application_query.rb +13 -0
- data/app/models/pageflow/application_record.rb +5 -0
- data/app/models/pageflow/audio_file.rb +1 -1
- data/app/models/pageflow/auto_snapshot_pruning.rb +26 -0
- data/app/models/pageflow/chapter.rb +4 -8
- data/app/models/pageflow/draft_entry.rb +2 -1
- data/app/models/pageflow/edit_lock.rb +11 -5
- data/app/models/pageflow/encoding_confirmation.rb +2 -1
- data/app/models/pageflow/entry.rb +13 -2
- data/app/models/pageflow/entry_publication.rb +2 -0
- data/app/models/pageflow/entry_role_query.rb +24 -9
- data/app/models/pageflow/entry_title_or_account_name_query.rb +33 -0
- data/app/models/pageflow/file_usage.rb +3 -7
- data/app/models/pageflow/folder.rb +1 -1
- data/app/models/pageflow/home_button.rb +1 -1
- data/app/models/pageflow/image_file.rb +22 -4
- data/app/models/pageflow/invitation_form.rb +10 -4
- data/app/models/pageflow/managed_user_query.rb +44 -0
- data/app/models/pageflow/membership.rb +1 -1
- data/app/models/pageflow/overview_button.rb +3 -4
- data/app/models/pageflow/page.rb +3 -7
- data/app/models/pageflow/potential_memberships.rb +112 -0
- data/app/models/pageflow/published_entry.rb +2 -1
- data/app/models/pageflow/revision.rb +13 -4
- data/app/models/pageflow/storyline.rb +3 -4
- data/app/models/pageflow/text_track_file.rb +1 -1
- data/app/models/pageflow/theming.rb +15 -10
- data/app/models/pageflow/url_template.rb +8 -2
- data/app/models/pageflow/user_name_query.rb +30 -0
- data/app/models/pageflow/video_file.rb +5 -1
- data/app/models/pageflow/widget.rb +3 -1
- data/app/models/pageflow/zencoder_attachment.rb +16 -5
- data/app/policies/pageflow/account_policy.rb +31 -61
- data/app/policies/pageflow/application_policy.rb +6 -0
- data/app/policies/pageflow/entry_policy.rb +11 -3
- data/app/policies/pageflow/membership_policy.rb +1 -2
- data/app/policies/pageflow/user_policy.rb +20 -1
- data/app/views/admin/accounts/_form.html.erb +4 -4
- data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +5 -0
- data/app/views/admin/memberships/_form.html.erb +9 -14
- data/app/views/admin/memberships/_role_hint.html.arb +1 -1
- data/app/views/admin/users/invitation.html.erb +18 -9
- data/app/views/admin/users/me.html.erb +2 -2
- data/app/views/admin/users/quota_state.html.erb +1 -0
- data/app/views/components/pageflow/admin/add_membership_button.rb +81 -0
- data/app/views/components/pageflow/admin/members_tab.rb +6 -4
- data/app/views/components/pageflow/admin/revisions_tab.rb +16 -4
- data/app/views/components/pageflow/admin/user_accounts_tab.rb +8 -2
- data/app/views/components/pageflow/admin/user_entries_tab.rb +6 -2
- data/app/views/components/pageflow/admin/users_tab.rb +9 -5
- data/app/views/layouts/pageflow/application.html.erb +2 -1
- data/app/views/pageflow/admin/users/_quota_exhausted.html.erb +1 -0
- data/app/views/pageflow/admin/users/_quota_state.html.erb +7 -0
- data/app/views/pageflow/config/_editor_seeds.json.jbuilder +2 -0
- data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
- data/app/views/pageflow/editor/entries/seed.json.erb +3 -1
- data/app/views/pageflow/editor/image_files/_image_file.json.jbuilder +1 -1
- data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -7
- data/app/views/pageflow/editor/widgets/_widget.json.jbuilder +1 -1
- data/app/views/pageflow/entries/_entry.html.erb +5 -5
- data/app/views/pageflow/entries/edit.html.erb +1 -1
- data/app/views/pageflow/entries/show.html.erb +1 -1
- data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +1 -0
- data/app/views/pageflow/themes/_theme.json.jbuilder +13 -0
- data/config/initializers/admin_resource_tabs.rb +19 -6
- data/config/initializers/features.rb +1 -0
- data/config/locales/de.yml +26 -3
- data/config/locales/en.yml +26 -3
- data/db/migrate/20170201074328_add_configuration_to_widgets.rb +5 -0
- data/db/migrate/20170222124848_update_video_file_output_presences.rb +1 -1
- data/db/migrate/20170315130000_add_theme_name_to_revisions.rb +12 -0
- data/db/migrate/20170912165050_reset_copied_snapshot_type.rb +24 -0
- data/lib/generators/pageflow/routes/routes_generator.rb +11 -1
- data/lib/generators/pageflow/seeds/seeds_generator.rb +5 -0
- data/lib/generators/pageflow/seeds/templates/seeds.rb +5 -3
- data/lib/generators/pageflow/theme/templates/preview.png +0 -0
- data/lib/generators/pageflow/theme/templates/preview_thumbnail.png +0 -0
- data/lib/generators/pageflow/theme/theme_generator.rb +3 -0
- data/lib/pageflow/ability_mixin.rb +27 -6
- data/lib/pageflow/active_admin_can_can_fix.rb +34 -0
- data/lib/pageflow/configuration/permissions.rb +27 -0
- data/lib/pageflow/configuration.rb +28 -0
- data/lib/pageflow/engine.rb +25 -19
- data/lib/pageflow/images/palette.png +0 -0
- data/lib/pageflow/seeds.rb +1 -1
- data/lib/pageflow/theme.rb +8 -0
- data/lib/pageflow/version.rb +1 -1
- data/lib/pageflow/widget_type.rb +13 -0
- data/lib/pageflow/zencoder_video_output_definition.rb +16 -16
- data/lib/tasks/pageflow_tasks.rake +14 -0
- data/spec/factories/entries.rb +4 -0
- data/spec/factories/revisions.rb +10 -0
- data/spec/factories/users.rb +6 -0
- data/spec/factories/video_files.rb +4 -0
- data/vendor/assets/javascripts/audio5.min.js +3 -0
- metadata +78 -15
- data/app/assets/javascripts/pageflow/editor/models/mixins/widget_subject.js +0 -37
- data/app/assets/javascripts/pageflow/editor/utils/reload_stylesheet.js +0 -9
- data/app/assets/stylesheets/pageflow/text_variants.scss +0 -24
- data/app/views/admin/accounts/_widgets_inline_help.html.erb +0 -5
- data/app/views/admin/memberships/_entity_account_input.html.erb +0 -5
- data/app/views/admin/memberships/_entity_entry_input.html.erb +0 -5
- data/app/views/admin/users/_quota_exhausted.html.erb +0 -1
- data/app/views/components/pageflow/admin/add_membership_button_if_needed.rb +0 -62
@@ -24,7 +24,7 @@ pageflow.EditMetaDataView = Backbone.Marionette.Layout.extend({
|
|
24
24
|
|
25
25
|
configurationEditor.tab('general', function() {
|
26
26
|
this.input('title', pageflow.TextInputView, {
|
27
|
-
placeholder: entry.
|
27
|
+
placeholder: entry.get('entry_title')
|
28
28
|
});
|
29
29
|
this.input('locale', pageflow.SelectInputView, {
|
30
30
|
values: pageflow.config.availablePublicLocales,
|
@@ -47,18 +47,20 @@ pageflow.EditMetaDataView = Backbone.Marionette.Layout.extend({
|
|
47
47
|
});
|
48
48
|
|
49
49
|
configurationEditor.tab('widgets', function() {
|
50
|
+
var theme = entry.getTheme();
|
51
|
+
|
50
52
|
this.input('manual_start', pageflow.CheckBoxInputView);
|
51
53
|
this.input('emphasize_chapter_beginning', pageflow.CheckBoxInputView);
|
52
54
|
this.input('emphasize_new_pages', pageflow.CheckBoxInputView);
|
53
55
|
this.input('home_button_enabled', pageflow.CheckBoxInputView, {
|
54
|
-
disabled: !
|
56
|
+
disabled: !theme.hasHomeButton(),
|
55
57
|
displayUncheckedIfDisabled: true
|
56
58
|
});
|
57
59
|
this.input('overview_button_enabled', pageflow.CheckBoxInputView, {
|
58
|
-
disabled: !
|
60
|
+
disabled: !theme.hasOverviewButton(),
|
59
61
|
displayUncheckedIfDisabled: true
|
60
62
|
});
|
61
|
-
if (
|
63
|
+
if (theme.hasHomeButton()) {
|
62
64
|
this.input('home_url', pageflow.TextInputView, {
|
63
65
|
placeholder: pageflow.theming.get('pretty_url'),
|
64
66
|
visibleBinding: 'home_button_enabled'
|
@@ -68,6 +70,13 @@ pageflow.EditMetaDataView = Backbone.Marionette.Layout.extend({
|
|
68
70
|
model: entry,
|
69
71
|
widgetTypes: pageflow.editor.widgetTypes
|
70
72
|
});
|
73
|
+
if (pageflow.features.isEnabled('selectable_themes') &&
|
74
|
+
pageflow.themes.length > 1) {
|
75
|
+
this.view(pageflow.ThemeInputView, {
|
76
|
+
themes: pageflow.themes,
|
77
|
+
propertyName: 'theme_name'
|
78
|
+
});
|
79
|
+
}
|
71
80
|
});
|
72
81
|
|
73
82
|
configurationEditor.tab('social', function() {
|
@@ -84,6 +93,10 @@ pageflow.EditMetaDataView = Backbone.Marionette.Layout.extend({
|
|
84
93
|
});
|
85
94
|
});
|
86
95
|
|
96
|
+
this.listenTo(entry.configuration, 'change:theme_name', function() {
|
97
|
+
configurationEditor.refresh();
|
98
|
+
});
|
99
|
+
|
87
100
|
this.formContainer.show(configurationEditor);
|
88
101
|
},
|
89
102
|
|
@@ -1,29 +1,19 @@
|
|
1
|
-
pageflow.EditWidgetView = Backbone.Marionette.
|
1
|
+
pageflow.EditWidgetView = Backbone.Marionette.ItemView.extend({
|
2
2
|
template: 'templates/edit_widget',
|
3
|
-
tagName: 'li',
|
4
3
|
className: 'edit_widget',
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
ui: {
|
11
|
-
role: 'h2'
|
5
|
+
events: {
|
6
|
+
'click a.back': function() {
|
7
|
+
editor.navigate('/meta_data/widgets', {trigger: true});
|
8
|
+
}
|
12
9
|
},
|
13
10
|
|
14
11
|
onRender: function() {
|
15
|
-
var
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
propertyName: 'type_name',
|
20
|
-
label: I18n.t('pageflow.widgets.roles.' + this.model.role()),
|
21
|
-
collection: widgetTypes,
|
22
|
-
valueProperty: 'name',
|
23
|
-
translationKeyProperty: 'translationKey',
|
24
|
-
includeBlank: true
|
25
|
-
}));
|
12
|
+
var configurationEditor = this.model.widgetType().createConfigurationEditorView({
|
13
|
+
model: this.model.configuration,
|
14
|
+
tab: this.options.tab
|
15
|
+
});
|
26
16
|
|
27
|
-
this
|
17
|
+
this.appendSubview(configurationEditor);
|
28
18
|
}
|
29
|
-
});
|
19
|
+
});
|
@@ -9,12 +9,10 @@ pageflow.EditWidgetsView = Backbone.Marionette.Layout.extend({
|
|
9
9
|
this.subview(new pageflow.CollectionView({
|
10
10
|
el: this.ui.widgets,
|
11
11
|
collection: this.model.widgets,
|
12
|
-
itemViewConstructor: pageflow.
|
12
|
+
itemViewConstructor: pageflow.WidgetItemView,
|
13
13
|
itemViewOptions: {
|
14
14
|
widgetTypes: this.options.widgetTypes
|
15
15
|
}
|
16
16
|
}).render());
|
17
|
-
|
18
|
-
this.model.fetchWidgets();
|
19
17
|
}
|
20
18
|
});
|
@@ -31,9 +31,13 @@ pageflow.FileMetaDataItemValueView = Backbone.Marionette.ItemView.extend({
|
|
31
31
|
}
|
32
32
|
},
|
33
33
|
|
34
|
+
modelEvents: {
|
35
|
+
'change': 'toggleEditLink'
|
36
|
+
},
|
37
|
+
|
34
38
|
onRender: function() {
|
35
39
|
this.listenTo(this.model, 'change:' + this.options.name, this.update);
|
36
|
-
this.
|
40
|
+
this.toggleEditLink();
|
37
41
|
|
38
42
|
this.update();
|
39
43
|
},
|
@@ -45,5 +49,10 @@ pageflow.FileMetaDataItemValueView = Backbone.Marionette.ItemView.extend({
|
|
45
49
|
|
46
50
|
getText: function() {
|
47
51
|
throw new Error('Not implemented');
|
52
|
+
},
|
53
|
+
|
54
|
+
toggleEditLink: function() {
|
55
|
+
this.ui.editLink.toggle(!!this.options.settingsDialogTabLink &&
|
56
|
+
!this.model.isNew());
|
48
57
|
}
|
49
58
|
});
|
@@ -14,6 +14,7 @@ pageflow.ReferenceInputView = Backbone.Marionette.ItemView.extend(
|
|
14
14
|
|
15
15
|
ui: {
|
16
16
|
title: '.title',
|
17
|
+
chooseButton: '.choose',
|
17
18
|
unsetButton: '.unset',
|
18
19
|
buttons: 'button'
|
19
20
|
},
|
@@ -22,8 +23,8 @@ pageflow.ReferenceInputView = Backbone.Marionette.ItemView.extend(
|
|
22
23
|
'click .choose': function() {
|
23
24
|
var view = this;
|
24
25
|
|
25
|
-
this.
|
26
|
-
view.model.set(view.options.propertyName,
|
26
|
+
this.chooseValue().then(function(id) {
|
27
|
+
view.model.set(view.options.propertyName, id);
|
27
28
|
});
|
28
29
|
|
29
30
|
return false;
|
@@ -44,11 +45,26 @@ pageflow.ReferenceInputView = Backbone.Marionette.ItemView.extend(
|
|
44
45
|
this.listenTo(this.model, 'change:' + this.options.propertyName, this.update);
|
45
46
|
},
|
46
47
|
|
48
|
+
/**
|
49
|
+
* Returns a promise for some identifying attribute.
|
50
|
+
*
|
51
|
+
* Default attribute name is perma_id. If the attribute is named
|
52
|
+
* differently, you can have your specific ReferenceInputView
|
53
|
+
* implement `chooseValue()` accordingly.
|
54
|
+
*
|
55
|
+
* Will be used to set the chosen Model for this View.
|
56
|
+
*/
|
57
|
+
chooseValue: function() {
|
58
|
+
return this.choose().then(function(model) {
|
59
|
+
return model.get('perma_id');
|
60
|
+
});
|
61
|
+
},
|
62
|
+
|
47
63
|
choose: function() {
|
48
64
|
throw 'Not implemented: Override ReferenceInputView#choose to return a promise';
|
49
65
|
},
|
50
66
|
|
51
|
-
getTarget: function() {
|
67
|
+
getTarget: function(targetId) {
|
52
68
|
throw 'Not implemented: Override ReferenceInputView#getTarget';
|
53
69
|
},
|
54
70
|
|
@@ -59,10 +75,26 @@ pageflow.ReferenceInputView = Backbone.Marionette.ItemView.extend(
|
|
59
75
|
},
|
60
76
|
|
61
77
|
update: function() {
|
78
|
+
if (this.isClosed) {
|
79
|
+
return;
|
80
|
+
}
|
81
|
+
|
62
82
|
var target = this.getTarget(this.model.get(this.options.propertyName));
|
63
83
|
|
64
84
|
this.ui.title.text(target ? target.title() : I18n.t('pageflow.editor.views.inputs.reference_input_view.none'));
|
65
|
-
|
85
|
+
|
86
|
+
this.ui.unsetButton.toggle(!!target && !this.options.hideUnsetButton);
|
87
|
+
this.ui.unsetButton.attr(
|
88
|
+
'title',
|
89
|
+
this.options.unsetButtonTitle ||
|
90
|
+
I18n.t('pageflow.editor.views.inputs.reference_input_view.unset')
|
91
|
+
);
|
92
|
+
|
93
|
+
this.ui.chooseButton.attr(
|
94
|
+
'title',
|
95
|
+
this.options.chooseButtonTitle ||
|
96
|
+
I18n.t('pageflow.editor.views.inputs.reference_input_view.choose')
|
97
|
+
);
|
66
98
|
|
67
99
|
this.updateDisabledAttribute(this.ui.buttons);
|
68
100
|
|
@@ -0,0 +1,26 @@
|
|
1
|
+
pageflow.ThemeInputView = pageflow.ReferenceInputView.extend({
|
2
|
+
options: function() {
|
3
|
+
return {
|
4
|
+
chooseButtonTitle: I18n.t('pageflow.editor.views.inputs.theme_input_view.choose'),
|
5
|
+
hideUnsetButton: true
|
6
|
+
};
|
7
|
+
},
|
8
|
+
|
9
|
+
choose: function() {
|
10
|
+
return pageflow.ChangeThemeDialogView.changeTheme({
|
11
|
+
model: this.model,
|
12
|
+
themes: this.options.themes,
|
13
|
+
themeInUse: this.model.get(this.options.propertyName)
|
14
|
+
});
|
15
|
+
},
|
16
|
+
|
17
|
+
chooseValue: function() {
|
18
|
+
return this.choose().then(function(model) {
|
19
|
+
return model.get('name');
|
20
|
+
});
|
21
|
+
},
|
22
|
+
|
23
|
+
getTarget: function(themeName) {
|
24
|
+
return this.options.themes.findByName(themeName);
|
25
|
+
}
|
26
|
+
});
|
@@ -17,24 +17,38 @@ pageflow.ModelThumbnailView = Backbone.Marionette.View.extend({
|
|
17
17
|
},
|
18
18
|
|
19
19
|
update: function() {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
if (this.model) {
|
21
|
+
if (_.isFunction(this.model.thumbnailFile)) {
|
22
|
+
var file = this.model && this.model.thumbnailFile();
|
23
|
+
|
24
|
+
if (this.thumbnailView && this.currentFileThumbnail == file) {
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
|
28
|
+
this.currentFileThumbnail = file;
|
29
|
+
|
30
|
+
this.newThumbnailView = new pageflow.FileThumbnailView({
|
31
|
+
model: file,
|
32
|
+
className: 'thumbnail file_thumbnail',
|
33
|
+
imageUrlPropertyName: this.options.imageUrlPropertyName
|
34
|
+
});
|
35
|
+
}
|
36
|
+
else {
|
37
|
+
this.newThumbnailView = this.newThumbnailView ||
|
38
|
+
new pageflow.StaticThumbnailView({
|
39
|
+
model: this.model
|
40
|
+
});
|
41
|
+
}
|
24
42
|
}
|
25
43
|
|
26
|
-
this.
|
27
|
-
|
28
|
-
if (this.fileThumbnailView) {
|
29
|
-
this.fileThumbnailView.close();
|
44
|
+
if (this.thumbnailView) {
|
45
|
+
this.thumbnailView.close();
|
30
46
|
}
|
31
47
|
|
32
|
-
|
33
|
-
|
34
|
-
className: 'thumbnail file_thumbnail',
|
35
|
-
imageUrlPropertyName: this.options.imageUrlPropertyName
|
36
|
-
}));
|
48
|
+
if (this.model) {
|
49
|
+
this.thumbnailView = this.subview(this.newThumbnailView);
|
37
50
|
|
38
|
-
|
51
|
+
this.$el.append(this.thumbnailView.el);
|
52
|
+
}
|
39
53
|
}
|
40
54
|
});
|
@@ -0,0 +1,20 @@
|
|
1
|
+
pageflow.StaticThumbnailView = Backbone.Marionette.ItemView.extend({
|
2
|
+
template: 'templates/static_thumbnail',
|
3
|
+
className: 'static_thumbnail',
|
4
|
+
|
5
|
+
modelEvents: {
|
6
|
+
'change:configuration': 'update'
|
7
|
+
},
|
8
|
+
|
9
|
+
onRender: function() {
|
10
|
+
this.update();
|
11
|
+
},
|
12
|
+
|
13
|
+
update: function() {
|
14
|
+
this.$el.css('background-image', 'url(' + this._imageUrl() + ')');
|
15
|
+
},
|
16
|
+
|
17
|
+
_imageUrl: function() {
|
18
|
+
return this.model.thumbnailUrl();
|
19
|
+
}
|
20
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/** @api private */
|
2
|
+
pageflow.ThemeItemView = Backbone.Marionette.ItemView.extend({
|
3
|
+
tagName: 'li',
|
4
|
+
template: 'pageflow/editor/templates/theme_item',
|
5
|
+
className: 'theme_item',
|
6
|
+
|
7
|
+
mixins: [pageflow.selectableView],
|
8
|
+
|
9
|
+
selectionAttribute: 'theme',
|
10
|
+
|
11
|
+
ui: {
|
12
|
+
themeName: '.theme_name',
|
13
|
+
useButton: '.use_theme',
|
14
|
+
inUseRegion: '.theme_in_use'
|
15
|
+
},
|
16
|
+
|
17
|
+
events: {
|
18
|
+
'click .use_theme': function() {
|
19
|
+
this.options.onUse(this.model);
|
20
|
+
},
|
21
|
+
'mouseenter': 'select',
|
22
|
+
'click': 'select'
|
23
|
+
},
|
24
|
+
|
25
|
+
onRender: function() {
|
26
|
+
this.$el.data('themeName', this.model.get('name'));
|
27
|
+
this.ui.themeName.text(this.model.title());
|
28
|
+
|
29
|
+
if (this.inUse()) {
|
30
|
+
this.ui.inUseRegion.text('✓');
|
31
|
+
}
|
32
|
+
|
33
|
+
this.ui.useButton.toggle(
|
34
|
+
!this.inUse()
|
35
|
+
);
|
36
|
+
},
|
37
|
+
|
38
|
+
inUse: function() {
|
39
|
+
return this.model.get('name') === this.options.themeInUse;
|
40
|
+
}
|
41
|
+
});
|
@@ -0,0 +1,49 @@
|
|
1
|
+
pageflow.WidgetItemView = Backbone.Marionette.Layout.extend({
|
2
|
+
template: 'templates/widget_item',
|
3
|
+
tagName: 'li',
|
4
|
+
className: 'widget_item',
|
5
|
+
|
6
|
+
regions: {
|
7
|
+
widgetTypeContainer: '.widget_type'
|
8
|
+
},
|
9
|
+
|
10
|
+
ui: {
|
11
|
+
role: 'h2'
|
12
|
+
},
|
13
|
+
|
14
|
+
modelEvents: {
|
15
|
+
'change:type_name': 'update'
|
16
|
+
},
|
17
|
+
|
18
|
+
events: {
|
19
|
+
'click .settings': function() {
|
20
|
+
pageflow.editor.navigate('/widgets/' + this.model.role(), {trigger: true});
|
21
|
+
return false;
|
22
|
+
},
|
23
|
+
},
|
24
|
+
|
25
|
+
onRender: function() {
|
26
|
+
var widgetTypes = this.options.widgetTypes.findAllByRole(this.model.role()) || [];
|
27
|
+
var isOptional = this.options.widgetTypes.isOptional(this.model.role());
|
28
|
+
|
29
|
+
this.widgetTypeContainer.show(new pageflow.SelectInputView({
|
30
|
+
model: this.model,
|
31
|
+
propertyName: 'type_name',
|
32
|
+
label: I18n.t('pageflow.widgets.roles.' + this.model.role()),
|
33
|
+
collection: widgetTypes,
|
34
|
+
valueProperty: 'name',
|
35
|
+
translationKeyProperty: 'translationKey',
|
36
|
+
includeBlank: isOptional || !this.model.get('type_name')
|
37
|
+
}));
|
38
|
+
|
39
|
+
this.$el.toggleClass('is_hidden', widgetTypes.length <= 1 &&
|
40
|
+
!this.model.hasConfiguration() &&
|
41
|
+
!isOptional);
|
42
|
+
|
43
|
+
this.update();
|
44
|
+
},
|
45
|
+
|
46
|
+
update: function() {
|
47
|
+
this.$el.toggleClass('has_settings', this.model.hasConfiguration());
|
48
|
+
}
|
49
|
+
});
|
@@ -8,6 +8,9 @@ pageflow.History = function(slideshow, adapter) {
|
|
8
8
|
if (options.back) {
|
9
9
|
adapter.replaceState(null, '', adapter.hash());
|
10
10
|
}
|
11
|
+
else if (options.ignoreInHistory) {
|
12
|
+
adapter.replaceState(null, '', hash);
|
13
|
+
}
|
11
14
|
else {
|
12
15
|
adapter.replaceState(options, '', adapter.hash());
|
13
16
|
adapter.pushState(null, '', hash);
|
@@ -28,8 +31,11 @@ pageflow.History = function(slideshow, adapter) {
|
|
28
31
|
slideshow.goToByPermaId(adapter.hash());
|
29
32
|
});
|
30
33
|
|
34
|
+
this.getLandingPagePermaId = function() {
|
35
|
+
return adapter.hash() || pageParameter();
|
36
|
+
};
|
37
|
+
|
31
38
|
this.start = function() {
|
32
|
-
slideshow.goToByPermaId(adapter.hash() || pageParameter());
|
33
39
|
adapter.replaceState(null, '', slideshow.currentPage().attr('id'));
|
34
40
|
};
|
35
41
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
pageflow.mediaPlayer.volumeFading.interval = function(player) {
|
2
|
+
var originalVolume = player.volume;
|
3
|
+
|
4
|
+
var fadeVolumeDeferred;
|
5
|
+
var fadeVolumeInterval;
|
6
|
+
|
7
|
+
player.volume = function(value) {
|
8
|
+
if (typeof value !== 'undefined') {
|
9
|
+
cancelFadeVolume();
|
10
|
+
}
|
11
|
+
|
12
|
+
return originalVolume.apply(player, arguments);
|
13
|
+
};
|
14
|
+
|
15
|
+
player.fadeVolume = function(value, duration) {
|
16
|
+
cancelFadeVolume();
|
17
|
+
|
18
|
+
return new $.Deferred(function(deferred) {
|
19
|
+
var resolution = 10;
|
20
|
+
var startValue = volume();
|
21
|
+
var steps = duration / resolution;
|
22
|
+
var leap = (value - startValue) / steps;
|
23
|
+
|
24
|
+
if (value === startValue) {
|
25
|
+
deferred.resolve();
|
26
|
+
}
|
27
|
+
else {
|
28
|
+
fadeVolumeDeferred = deferred;
|
29
|
+
fadeVolumeInterval = setInterval(function() {
|
30
|
+
volume(volume() + leap);
|
31
|
+
|
32
|
+
if ((volume() >= value && value >= startValue) ||
|
33
|
+
(volume() <= value && value <= startValue)) {
|
34
|
+
|
35
|
+
resolveFadeVolume();
|
36
|
+
}
|
37
|
+
}, resolution);
|
38
|
+
}
|
39
|
+
});
|
40
|
+
};
|
41
|
+
|
42
|
+
player.one('dispose', cancelFadeVolume);
|
43
|
+
|
44
|
+
function volume(/* arguments */) {
|
45
|
+
return originalVolume.apply(player, arguments);
|
46
|
+
}
|
47
|
+
|
48
|
+
function resolveFadeVolume() {
|
49
|
+
clearInterval(fadeVolumeInterval);
|
50
|
+
fadeVolumeDeferred.resolve();
|
51
|
+
|
52
|
+
fadeVolumeInterval = null;
|
53
|
+
fadeVolumeDeferred = null;
|
54
|
+
}
|
55
|
+
|
56
|
+
function cancelFadeVolume() {
|
57
|
+
if (fadeVolumeInterval) {
|
58
|
+
clearInterval(fadeVolumeInterval);
|
59
|
+
fadeVolumeDeferred.reject();
|
60
|
+
|
61
|
+
fadeVolumeInterval = null;
|
62
|
+
fadeVolumeDeferred = null;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
};
|
@@ -0,0 +1,109 @@
|
|
1
|
+
pageflow.mediaPlayer.volumeFading.webAudio = function(player, audioContext) {
|
2
|
+
var gainNode;
|
3
|
+
|
4
|
+
var currentDeferred;
|
5
|
+
var currentTimeout;
|
6
|
+
|
7
|
+
var currentValue = 1;
|
8
|
+
|
9
|
+
var lastStartTime;
|
10
|
+
var lastDuration;
|
11
|
+
var lastStartValue;
|
12
|
+
|
13
|
+
var allowedMinValue = 0.000001;
|
14
|
+
|
15
|
+
player.volume = function(value) {
|
16
|
+
ensureGainNode();
|
17
|
+
|
18
|
+
if (typeof value !== 'undefined') {
|
19
|
+
cancel();
|
20
|
+
currentValue = ensureInAllowedRange(value);
|
21
|
+
|
22
|
+
return gainNode.gain.setValueAtTime(currentValue,
|
23
|
+
audioContext.currentTime);
|
24
|
+
}
|
25
|
+
|
26
|
+
return Math.round(currentValue * 100) / 100;
|
27
|
+
};
|
28
|
+
|
29
|
+
player.fadeVolume = function(value, duration) {
|
30
|
+
ensureGainNode();
|
31
|
+
|
32
|
+
cancel();
|
33
|
+
recordFadeStart(duration);
|
34
|
+
|
35
|
+
currentValue = ensureInAllowedRange(value);
|
36
|
+
|
37
|
+
gainNode.gain.setValueAtTime(lastStartValue, audioContext.currentTime);
|
38
|
+
gainNode.gain.linearRampToValueAtTime(currentValue,
|
39
|
+
audioContext.currentTime + duration / 1000);
|
40
|
+
|
41
|
+
return new $.Deferred(function(deferred) {
|
42
|
+
currentTimeout = setTimeout(resolve, duration);
|
43
|
+
currentDeferred = deferred;
|
44
|
+
}).promise();
|
45
|
+
};
|
46
|
+
|
47
|
+
player.one('dispose', cancel);
|
48
|
+
|
49
|
+
function ensureGainNode() {
|
50
|
+
if (!gainNode) {
|
51
|
+
gainNode = audioContext.createGain();
|
52
|
+
|
53
|
+
var source = audioContext.createMediaElementSource(player.getMediaElement());
|
54
|
+
|
55
|
+
source.connect(gainNode);
|
56
|
+
gainNode.connect(audioContext.destination);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
function resolve() {
|
61
|
+
clearTimeout(currentTimeout);
|
62
|
+
currentDeferred.resolve();
|
63
|
+
|
64
|
+
currentTimeout = null;
|
65
|
+
currentDeferred = null;
|
66
|
+
}
|
67
|
+
|
68
|
+
function cancel() {
|
69
|
+
if (currentDeferred) {
|
70
|
+
gainNode.gain.cancelScheduledValues(audioContext.currentTime);
|
71
|
+
|
72
|
+
clearTimeout(currentTimeout);
|
73
|
+
currentDeferred.reject();
|
74
|
+
|
75
|
+
currentTimeout = null;
|
76
|
+
currentDeferred = null;
|
77
|
+
|
78
|
+
updateCurrentValueFromComputedValue();
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
function recordFadeStart(duration) {
|
83
|
+
lastStartTime = audioContext.currentTime;
|
84
|
+
lastStartValue = currentValue;
|
85
|
+
lastDuration = duration;
|
86
|
+
}
|
87
|
+
|
88
|
+
function updateCurrentValueFromComputedValue() {
|
89
|
+
// Firefox 54 on Ubuntu does not provide computed values when gain
|
90
|
+
// was changed via one of the scheduling methods. Instead
|
91
|
+
// gain.value always reports 1. Interpolate manually do determine
|
92
|
+
// how far the fade was performed before cancel was called.
|
93
|
+
if (gainNode.gain.value == 1) {
|
94
|
+
var performedDuration = (audioContext.currentTime - lastStartTime) * 1000;
|
95
|
+
var lastDelta = currentValue - lastStartValue;
|
96
|
+
|
97
|
+
currentValue = ensureInAllowedRange(
|
98
|
+
lastStartValue + (performedDuration / lastDuration * lastDelta)
|
99
|
+
);
|
100
|
+
}
|
101
|
+
else {
|
102
|
+
currentValue = gainNode.gain.value;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
function ensureInAllowedRange(value) {
|
107
|
+
return value < allowedMinValue ? allowedMinValue : value;
|
108
|
+
}
|
109
|
+
};
|