pageflow 15.1.0.beta6 → 15.1.0.rc0
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 +17 -0
- data/app/assets/javascripts/pageflow/dist/editor.js +613 -94
- data/app/assets/javascripts/pageflow/dist/ui.js +120 -3
- data/app/assets/stylesheets/pageflow/editor/base.scss +1 -0
- data/app/assets/stylesheets/pageflow/editor/composables.scss +9 -0
- data/app/assets/stylesheets/pageflow/editor/file_import.scss +7 -8
- data/app/helpers/pageflow/config_helper.rb +1 -1
- data/app/helpers/pageflow/entries_helper.rb +6 -1
- data/app/helpers/pageflow/social_share_links_helper.rb +5 -1
- data/config/locales/de.yml +34 -16
- data/config/locales/en.yml +34 -16
- data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +613 -93
- data/entry_types/paged/app/views/layouts/pageflow_paged/application.html.erb +2 -1
- data/entry_types/paged/lib/pageflow_paged/engine.rb +1 -0
- data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +9 -1
- data/entry_types/scrolled/app/helpers/pageflow_scrolled/entry_json_seed_helper.rb +2 -0
- data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +28 -0
- data/entry_types/scrolled/config/locales/new/de.yml +46 -0
- data/entry_types/scrolled/config/locales/new/en.yml +46 -0
- data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +1 -0
- data/entry_types/scrolled/package/editor.js +2844 -78
- data/entry_types/scrolled/package/frontend.js +955 -443
- data/entry_types/scrolled/package/package.json +1 -0
- data/lib/pageflow/version.rb +1 -1
- data/packages/pageflow/editor.js +485 -90
- data/packages/pageflow/ui.js +120 -3
- metadata +5 -4
- data/config/locales/new/entry_metadata_configuration.de.yml +0 -17
- data/config/locales/new/entry_metadata_configuration.en.yml +0 -17
data/lib/pageflow/version.rb
CHANGED
data/packages/pageflow/editor.js
CHANGED
@@ -725,6 +725,62 @@ _$1.each(['each', 'map', 'reduce', 'first', 'find', 'pluck'], function (method)
|
|
725
725
|
};
|
726
726
|
});
|
727
727
|
|
728
|
+
// different model types. Backbone.Collection tries to merge records
|
729
|
+
// if they have the same id.
|
730
|
+
|
731
|
+
var MultiCollection = function MultiCollection() {
|
732
|
+
this.records = {};
|
733
|
+
this.length = 0;
|
734
|
+
};
|
735
|
+
|
736
|
+
_$1.extend(MultiCollection.prototype, {
|
737
|
+
add: function add(record) {
|
738
|
+
if (!this.records[record.cid]) {
|
739
|
+
this.records[record.cid] = record;
|
740
|
+
this.length = _$1.keys(this.records).length;
|
741
|
+
this.trigger('add', record);
|
742
|
+
}
|
743
|
+
},
|
744
|
+
remove: function remove(record) {
|
745
|
+
if (this.records[record.cid]) {
|
746
|
+
delete this.records[record.cid];
|
747
|
+
this.length = _$1.keys(this.records).length;
|
748
|
+
this.trigger('remove', record);
|
749
|
+
}
|
750
|
+
},
|
751
|
+
isEmpty: function isEmpty() {
|
752
|
+
return this.length === 0;
|
753
|
+
}
|
754
|
+
});
|
755
|
+
|
756
|
+
_$1.extend(MultiCollection.prototype, Backbone.Events);
|
757
|
+
|
758
|
+
MultiCollection.extend = Backbone.Collection.extend;
|
759
|
+
|
760
|
+
/**
|
761
|
+
* Watch Backbone collections to track which models are currently
|
762
|
+
* being saved. Used to update the notifications view displaying
|
763
|
+
* saving status/failutes.
|
764
|
+
*/
|
765
|
+
|
766
|
+
var SavingRecordsCollection = MultiCollection.extend({
|
767
|
+
/**
|
768
|
+
* Listen to events of models in collection to track when they are
|
769
|
+
* being saved.
|
770
|
+
*
|
771
|
+
* @param {Backbone.Collection} collection - Collection to watch.
|
772
|
+
*/
|
773
|
+
watch: function watch(collection) {
|
774
|
+
var that = this;
|
775
|
+
this.listenTo(collection, 'request', function (model, xhr) {
|
776
|
+
that.add(model);
|
777
|
+
xhr.always(function () {
|
778
|
+
that.remove(model);
|
779
|
+
});
|
780
|
+
});
|
781
|
+
}
|
782
|
+
});
|
783
|
+
|
728
784
|
var WidgetType = Object$1.extend({
|
729
785
|
initialize: function initialize(serverSideConfig, clientSideConfig) {
|
730
786
|
this.name = serverSideConfig.name;
|
@@ -814,6 +870,15 @@ var EditorApi = Object$1.extend(
|
|
814
870
|
*/
|
815
871
|
|
816
872
|
this.failures = new FailuresAPI();
|
873
|
+
/**
|
874
|
+
* Tracking records that are currently being saved.
|
875
|
+
*
|
876
|
+
* @returns {SavingRecordsCollection}
|
877
|
+
* @memberof editor
|
878
|
+
* @since edge
|
879
|
+
*/
|
880
|
+
|
881
|
+
this.savingRecords = new SavingRecordsCollection();
|
817
882
|
/**
|
818
883
|
* Set up editor integration for page types.
|
819
884
|
* @memberof editor
|
@@ -860,7 +925,9 @@ var EditorApi = Object$1.extend(
|
|
860
925
|
* Backbone view that will be rendered in the side bar.
|
861
926
|
*/
|
862
927
|
registerEntryType: function registerEntryType(name, options) {
|
863
|
-
this.entryType =
|
928
|
+
this.entryType = _objectSpread({
|
929
|
+
name: name
|
930
|
+
}, options);
|
864
931
|
},
|
865
932
|
createEntryModel: function createEntryModel(seed, options) {
|
866
933
|
var entry = new this.entryType.entryModel(seed.entry, options);
|
@@ -1074,6 +1141,79 @@ var startEditor = function startEditor(options) {
|
|
1074
1141
|
});
|
1075
1142
|
};
|
1076
1143
|
|
1144
|
+
/**
|
1145
|
+
* Mixins for Backbone models and collections that use entry type
|
1146
|
+
* specific editor controllers registered via the `editor_app` entry
|
1147
|
+
* type option.
|
1148
|
+
*/
|
1149
|
+
|
1150
|
+
var entryTypeEditorControllerUrls = {
|
1151
|
+
/**
|
1152
|
+
* Mixins for Backbone collections that defines `url` method.
|
1153
|
+
*
|
1154
|
+
* @param {Object} options
|
1155
|
+
* @param {String} options.resources - Path suffix of the controller route
|
1156
|
+
*
|
1157
|
+
* @example
|
1158
|
+
*
|
1159
|
+
* import {editor, entryTypeEditorControllerUrls} from 'pageflow/editor';
|
1160
|
+
*
|
1161
|
+
* editor.registerEntryType('test', {
|
1162
|
+
// ...
|
1163
|
+
});
|
1164
|
+
*
|
1165
|
+
* export const ItemsCollection = Backbone.Collection.extend({
|
1166
|
+
* mixins: [entryTypeEditorControllerUrls.forCollection({resources: 'items'})
|
1167
|
+
* });
|
1168
|
+
*
|
1169
|
+
* new ItemsCollection().url() // => '/editor/entries/10/test/items'
|
1170
|
+
*/
|
1171
|
+
forCollection: function forCollection(_ref) {
|
1172
|
+
var resources = _ref.resources;
|
1173
|
+
return {
|
1174
|
+
url: function url() {
|
1175
|
+
return entryTypeEditorControllerUrl(resources);
|
1176
|
+
},
|
1177
|
+
urlSuffix: function urlSuffix() {
|
1178
|
+
return "/".concat(resources);
|
1179
|
+
}
|
1180
|
+
};
|
1181
|
+
},
|
1182
|
+
|
1183
|
+
/**
|
1184
|
+
* Mixins for Backbone models that defines `urlRoot` method.
|
1185
|
+
*
|
1186
|
+
* @param {Object} options
|
1187
|
+
* @param {String} options.resources - Path suffix of the controller route
|
1188
|
+
*
|
1189
|
+
* @example
|
1190
|
+
*
|
1191
|
+
* import {editor, entryTypeEditorControllerUrls} from 'pageflow/editor';
|
1192
|
+
*
|
1193
|
+
* editor.registerEntryType('test', {
|
1194
|
+
// ...
|
1195
|
+
});
|
1196
|
+
*
|
1197
|
+
* export const Item = Backbone.Model.extend({
|
1198
|
+
* mixins: [entryTypeEditorControllerUrls.forModel({resources: 'items'})
|
1199
|
+
* });
|
1200
|
+
*
|
1201
|
+
* new Item({id: 20}).url() // => '/editor/entries/10/test/items/20'
|
1202
|
+
*/
|
1203
|
+
forModel: function forModel(_ref2) {
|
1204
|
+
var resources = _ref2.resources;
|
1205
|
+
return {
|
1206
|
+
urlRoot: function urlRoot() {
|
1207
|
+
return this.isNew() ? this.collection.url() : entryTypeEditorControllerUrl(resources);
|
1208
|
+
}
|
1209
|
+
};
|
1210
|
+
}
|
1211
|
+
};
|
1212
|
+
|
1213
|
+
function entryTypeEditorControllerUrl(resources) {
|
1214
|
+
return [state.entry.url(), editor$1.entryType.name, resources].join('/');
|
1215
|
+
}
|
1216
|
+
|
1077
1217
|
var formDataUtils = {
|
1078
1218
|
fromModel: function fromModel(model) {
|
1079
1219
|
var object = {};
|
@@ -1181,7 +1321,7 @@ var SubsetCollection = Backbone.Collection.extend({
|
|
1181
1321
|
this.reset();
|
1182
1322
|
},
|
1183
1323
|
url: function url() {
|
1184
|
-
return this.parentModel.url() + _$1.result(this.parent, 'url');
|
1324
|
+
return this.parentModel.url() + (_$1.result(this.parent, 'urlSuffix') || _$1.result(this.parent, 'url'));
|
1185
1325
|
},
|
1186
1326
|
dispose: function dispose() {
|
1187
1327
|
this.stopListening();
|
@@ -1490,10 +1630,23 @@ app.on('mixin:configuration', function (mixin) {
|
|
1490
1630
|
Cocktail.mixin(Configuration, mixin);
|
1491
1631
|
});
|
1492
1632
|
|
1633
|
+
/**
|
1634
|
+
* Remove model from collection only after the `DELETE` request has
|
1635
|
+
* succeeded. Still allow tracking that the model is being destroyed
|
1636
|
+
* by triggering a `destroying` event and adding a `isDestroying`
|
1637
|
+
* method.
|
1638
|
+
*/
|
1639
|
+
|
1493
1640
|
var delayedDestroying = {
|
1494
1641
|
initialize: function initialize() {
|
1495
1642
|
this._destroying = false;
|
1643
|
+
this._destroyed = false;
|
1496
1644
|
},
|
1645
|
+
|
1646
|
+
/**
|
1647
|
+
* Trigger `destroying` event and send `DELETE` request. Only remove
|
1648
|
+
* model from collection once the request is done.
|
1649
|
+
*/
|
1497
1650
|
destroyWithDelay: function destroyWithDelay() {
|
1498
1651
|
var model = this;
|
1499
1652
|
this._destroying = true;
|
@@ -1502,17 +1655,33 @@ var delayedDestroying = {
|
|
1502
1655
|
wait: true,
|
1503
1656
|
success: function success() {
|
1504
1657
|
model._destroying = false;
|
1658
|
+
model._destroyed = true;
|
1505
1659
|
},
|
1506
1660
|
error: function error() {
|
1507
1661
|
model._destroying = false;
|
1508
1662
|
}
|
1509
1663
|
});
|
1510
1664
|
},
|
1665
|
+
|
1666
|
+
/**
|
1667
|
+
* Get whether the model is currently being destroyed.
|
1668
|
+
*/
|
1511
1669
|
isDestroying: function isDestroying() {
|
1512
1670
|
return this._destroying;
|
1671
|
+
},
|
1672
|
+
|
1673
|
+
/**
|
1674
|
+
* Get whether the model has been destroyed.
|
1675
|
+
*/
|
1676
|
+
isDestroyed: function isDestroyed() {
|
1677
|
+
return this._destroyed;
|
1513
1678
|
}
|
1514
1679
|
};
|
1515
1680
|
|
1681
|
+
/**
|
1682
|
+
* Mixin for Backbone models that shall be watched by {@link
|
1683
|
+
* modelLifecycleTrackingView} mixin.
|
1684
|
+
*/
|
1516
1685
|
var failureTracking = {
|
1517
1686
|
initialize: function initialize() {
|
1518
1687
|
this._saveFailed = false;
|
@@ -2971,6 +3140,76 @@ var PageLinkFileSelectionHandler = function PageLinkFileSelectionHandler(options
|
|
2971
3140
|
};
|
2972
3141
|
editor$1.registerFileSelectionHandler('pageLink', PageLinkFileSelectionHandler);
|
2973
3142
|
|
3143
|
+
/**
|
3144
|
+
* Mixins for models with a nested configuration model.
|
3145
|
+
*
|
3146
|
+
* Triggers events on the parent model of the form
|
3147
|
+
* `change:configuration` and `change:configuration:<attribute>`, when
|
3148
|
+
* the configuration changes.
|
3149
|
+
*
|
3150
|
+
* @param {Object} [options]
|
3151
|
+
* @param {Function} [options.configurationModel] -
|
3152
|
+
* Backbone model to use for nested configuration model.
|
3153
|
+
* @param {Boolean} [options.autoSave] -
|
3154
|
+
* Save model when configuration changes.
|
3155
|
+
* @param {Boolean|Array<String>} [options.includeAttributesInJSON] -
|
3156
|
+
* Include all or specific attributes of the parent model in the
|
3157
|
+
* data returned by `toJSON` besides the `configuration` property.
|
3158
|
+
* @returns {Object} - Mixin to be included in model.
|
3159
|
+
*
|
3160
|
+
* @example
|
3161
|
+
*
|
3162
|
+
* import {configurationContainer} from 'pageflow/editor';
|
3163
|
+
*
|
3164
|
+
* const Section = Backbone.Model.extend({
|
3165
|
+
* mixins: [configurationContainer({autoSave: true})]
|
3166
|
+
* });
|
3167
|
+
*
|
3168
|
+
* const section = new Section({configuration: {some: 'value'}});
|
3169
|
+
* section.configuration.get('some') // => 'value';
|
3170
|
+
*/
|
3171
|
+
|
3172
|
+
function configurationContainer() {
|
3173
|
+
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
3174
|
+
configurationModel = _ref.configurationModel,
|
3175
|
+
autoSave = _ref.autoSave,
|
3176
|
+
includeAttributesInJSON = _ref.includeAttributesInJSON;
|
3177
|
+
|
3178
|
+
configurationModel = configurationModel || Configuration.extend({
|
3179
|
+
defaults: {}
|
3180
|
+
});
|
3181
|
+
return {
|
3182
|
+
initialize: function initialize() {
|
3183
|
+
this.configuration = new configurationModel(this.get('configuration'));
|
3184
|
+
this.configuration.parent = this;
|
3185
|
+
this.listenTo(this.configuration, 'change', function () {
|
3186
|
+
if (!this.isNew() && (!this.isDestroying || !this.isDestroying()) && (!this.isDestroyed || !this.isDestroyed()) && autoSave) {
|
3187
|
+
this.save();
|
3188
|
+
}
|
3189
|
+
|
3190
|
+
this.trigger('change:configuration', this);
|
3191
|
+
|
3192
|
+
_$1.chain(this.configuration.changed).keys().each(function (name) {
|
3193
|
+
this.trigger('change:configuration:' + name, this, this.configuration.get(name));
|
3194
|
+
}, this);
|
3195
|
+
});
|
3196
|
+
},
|
3197
|
+
toJSON: function toJSON() {
|
3198
|
+
var attributes = {};
|
3199
|
+
|
3200
|
+
if (includeAttributesInJSON === true) {
|
3201
|
+
attributes = _$1.clone(this.attributes);
|
3202
|
+
} else if (includeAttributesInJSON) {
|
3203
|
+
attributes = _$1.pick(this.attributes, includeAttributesInJSON);
|
3204
|
+
}
|
3205
|
+
|
3206
|
+
return _$1.extend(attributes, {
|
3207
|
+
configuration: this.configuration.toJSON()
|
3208
|
+
});
|
3209
|
+
}
|
3210
|
+
};
|
3211
|
+
}
|
3212
|
+
|
2974
3213
|
var persistedPromise = {
|
2975
3214
|
persisted: function persisted() {
|
2976
3215
|
var model = this;
|
@@ -3334,6 +3573,61 @@ var ChaptersCollection = Backbone.Collection.extend({
|
|
3334
3573
|
}
|
3335
3574
|
});
|
3336
3575
|
|
3576
|
+
/**
|
3577
|
+
* A Backbone collection that is automatically updated to only
|
3578
|
+
* contain models with a foreign key matching the id of a parent
|
3579
|
+
* model.
|
3580
|
+
*
|
3581
|
+
* @param {Object} options
|
3582
|
+
* @param {Backbone.Model} options.parentModel -
|
3583
|
+
* Model whose id is compared to foreign keys.
|
3584
|
+
* @param {Backbone.Collection} options.parent -
|
3585
|
+
* Collection to filter items with matching foreign key from.
|
3586
|
+
* @param {String} options.foreignKeyAttribute -
|
3587
|
+
* Attribute to compare to id of parent model.
|
3588
|
+
* @param {String} options.parentReferenceAttribute -
|
3589
|
+
* Set reference to parent model on models in collection.
|
3590
|
+
*
|
3591
|
+
* @since edge
|
3592
|
+
*/
|
3593
|
+
|
3594
|
+
var ForeignKeySubsetCollection = SubsetCollection.extend({
|
3595
|
+
mixins: [orderedCollection],
|
3596
|
+
constructor: function constructor(options) {
|
3597
|
+
var parent = options.parent;
|
3598
|
+
var parentModel = options.parentModel;
|
3599
|
+
SubsetCollection.prototype.constructor.call(this, {
|
3600
|
+
parent: parent,
|
3601
|
+
parentModel: parentModel,
|
3602
|
+
filter: function filter(item) {
|
3603
|
+
return !parentModel.isNew() && item.get(options.foreignKeyAttribute) === parentModel.id;
|
3604
|
+
},
|
3605
|
+
comparator: function comparator(item) {
|
3606
|
+
return item.get('position');
|
3607
|
+
}
|
3608
|
+
});
|
3609
|
+
this.listenTo(this, 'add', function (model) {
|
3610
|
+
if (options.parentReferenceAttribute) {
|
3611
|
+
model[options.parentReferenceAttribute] = parentModel;
|
3612
|
+
}
|
3613
|
+
|
3614
|
+
model.set(options.foreignKeyAttribute, parentModel.id);
|
3615
|
+
});
|
3616
|
+
this.listenTo(parentModel, 'destroy', function () {
|
3617
|
+
this.clear();
|
3618
|
+
});
|
3619
|
+
|
3620
|
+
if (options.parentReferenceAttribute) {
|
3621
|
+
this.each(function (model) {
|
3622
|
+
return model[options.parentReferenceAttribute] = parentModel;
|
3623
|
+
});
|
3624
|
+
this.listenTo(this, 'remove', function (model) {
|
3625
|
+
model[options.parentReferenceAttribute] = null;
|
3626
|
+
});
|
3627
|
+
}
|
3628
|
+
}
|
3629
|
+
});
|
3630
|
+
|
3337
3631
|
var PageLinksCollection = Backbone.Collection.extend({
|
3338
3632
|
model: PageLink,
|
3339
3633
|
initialize: function initialize(models, options) {
|
@@ -3553,50 +3847,6 @@ var addAndReturnModel = {
|
|
3553
3847
|
};
|
3554
3848
|
Cocktail.mixin(Backbone.Collection, addAndReturnModel);
|
3555
3849
|
|
3556
|
-
// different model types. Backbone.Collection tries to merge records
|
3557
|
-
// if they have the same id.
|
3558
|
-
|
3559
|
-
var MultiCollection = function MultiCollection() {
|
3560
|
-
this.records = {};
|
3561
|
-
this.length = 0;
|
3562
|
-
};
|
3563
|
-
|
3564
|
-
_$1.extend(MultiCollection.prototype, {
|
3565
|
-
add: function add(record) {
|
3566
|
-
if (!this.records[record.cid]) {
|
3567
|
-
this.records[record.cid] = record;
|
3568
|
-
this.length = _$1.keys(this.records).length;
|
3569
|
-
this.trigger('add', record);
|
3570
|
-
}
|
3571
|
-
},
|
3572
|
-
remove: function remove(record) {
|
3573
|
-
if (this.records[record.cid]) {
|
3574
|
-
delete this.records[record.cid];
|
3575
|
-
this.length = _$1.keys(this.records).length;
|
3576
|
-
this.trigger('remove', record);
|
3577
|
-
}
|
3578
|
-
},
|
3579
|
-
isEmpty: function isEmpty() {
|
3580
|
-
return this.length === 0;
|
3581
|
-
}
|
3582
|
-
});
|
3583
|
-
|
3584
|
-
_$1.extend(MultiCollection.prototype, Backbone.Events);
|
3585
|
-
|
3586
|
-
MultiCollection.extend = Backbone.Collection.extend;
|
3587
|
-
|
3588
|
-
var SavingRecordsCollection = MultiCollection.extend({
|
3589
|
-
watch: function watch(collection) {
|
3590
|
-
var that = this;
|
3591
|
-
this.listenTo(collection, 'request', function (model, xhr) {
|
3592
|
-
that.add(model);
|
3593
|
-
xhr.always(function () {
|
3594
|
-
that.remove(model);
|
3595
|
-
});
|
3596
|
-
});
|
3597
|
-
}
|
3598
|
-
});
|
3599
|
-
|
3600
3850
|
var SidebarRouter = Marionette.AppRouter.extend({
|
3601
3851
|
appRoutes: {
|
3602
3852
|
'page_links/:id': 'pageLink',
|
@@ -3777,24 +4027,87 @@ ConfirmEncodingView.create = function (options) {
|
|
3777
4027
|
});
|
3778
4028
|
};
|
3779
4029
|
|
3780
|
-
|
3781
|
-
|
3782
|
-
|
3783
|
-
|
3784
|
-
|
3785
|
-
|
4030
|
+
/**
|
4031
|
+
* Mixin for Marionette Views that sets css class names according to
|
4032
|
+
* life cycle events of its model.
|
4033
|
+
*
|
4034
|
+
* @param {Object} options
|
4035
|
+
* @param {Object} options.classNames
|
4036
|
+
* @param {String} options.classNames.creating -
|
4037
|
+
* Class name to add to root element while model is still being created.
|
4038
|
+
* @param {String} options.classNames.destroying -
|
4039
|
+
* Class name to add to root element while model is being destroyed.
|
4040
|
+
* @param {String} options.classNames.failed -
|
4041
|
+
* Class name to add to root element while model is in failed state.
|
4042
|
+
* Model needs to include {@link failureTracking} mixin.
|
4043
|
+
* @param {String} options.classNames.failureMessage -
|
4044
|
+
* Class name of the element that shall be updated with the failure
|
4045
|
+
* message. Model needs to include {@link failureTracking} mixin.
|
4046
|
+
* @param {String} options.classNames.retryButton -
|
4047
|
+
* Class name of the element that shall act as a retry button.
|
4048
|
+
*/
|
4049
|
+
|
4050
|
+
function modelLifecycleTrackingView(_ref) {
|
4051
|
+
var classNames = _ref.classNames;
|
4052
|
+
return {
|
4053
|
+
events: _defineProperty({}, "click .".concat(classNames.retryButton), function click() {
|
3786
4054
|
editor$1.failures.retry();
|
3787
4055
|
return false;
|
4056
|
+
}),
|
4057
|
+
initialize: function initialize() {
|
4058
|
+
var _this = this;
|
4059
|
+
|
4060
|
+
if (classNames.creating) {
|
4061
|
+
this.listenTo(this.model, 'change:id', function () {
|
4062
|
+
this.$el.removeClass(classNames.creating);
|
4063
|
+
});
|
4064
|
+
}
|
4065
|
+
|
4066
|
+
if (classNames.destroying) {
|
4067
|
+
this.listenTo(this.model, 'destroying', function () {
|
4068
|
+
this.$el.addClass(classNames.destroying);
|
4069
|
+
});
|
4070
|
+
this.listenTo(this.model, 'error', function () {
|
4071
|
+
this.$el.removeClass(classNames.destroying);
|
4072
|
+
});
|
4073
|
+
}
|
4074
|
+
|
4075
|
+
if (classNames.failed || classNames.failureMessage) {
|
4076
|
+
this.listenTo(this.model, 'change:failed', function () {
|
4077
|
+
return _this.updateFailIndicator();
|
4078
|
+
});
|
4079
|
+
}
|
4080
|
+
},
|
4081
|
+
render: function render() {
|
4082
|
+
if (this.model.isNew()) {
|
4083
|
+
this.$el.addClass(classNames.creating);
|
4084
|
+
}
|
4085
|
+
|
4086
|
+
if (this.model.isDestroying && this.model.isDestroying()) {
|
4087
|
+
this.$el.addClass(classNames.destroying);
|
4088
|
+
}
|
4089
|
+
|
4090
|
+
this.updateFailIndicator();
|
4091
|
+
},
|
4092
|
+
updateFailIndicator: function updateFailIndicator() {
|
4093
|
+
if (classNames.failed) {
|
4094
|
+
this.$el.toggleClass(classNames.failed, this.model.isFailed());
|
4095
|
+
}
|
4096
|
+
|
4097
|
+
if (classNames.failureMessage) {
|
4098
|
+
this.$el.find(".".concat(classNames.failureMessage)).text(this.model.getFailureMessage());
|
4099
|
+
}
|
3788
4100
|
}
|
3789
|
-
}
|
3790
|
-
|
3791
|
-
|
3792
|
-
|
3793
|
-
|
3794
|
-
|
3795
|
-
|
4101
|
+
};
|
4102
|
+
}
|
4103
|
+
|
4104
|
+
var failureIndicatingView = modelLifecycleTrackingView({
|
4105
|
+
classNames: {
|
4106
|
+
failed: 'failed',
|
4107
|
+
failureMessage: 'failure .message',
|
4108
|
+
retryButton: 'retry'
|
3796
4109
|
}
|
3797
|
-
};
|
4110
|
+
});
|
3798
4111
|
|
3799
4112
|
function template$6(data) {
|
3800
4113
|
var __t, __p = '';
|
@@ -4987,7 +5300,8 @@ var EditMetaDataView = Marionette.Layout.extend({
|
|
4987
5300
|
var editor = this.options.editor || {};
|
4988
5301
|
var configurationEditor = new ConfigurationEditorView({
|
4989
5302
|
model: entry.metadata.configuration,
|
4990
|
-
tab: this.options.tab
|
5303
|
+
tab: this.options.tab,
|
5304
|
+
attributeTranslationKeyPrefixes: ['pageflow.entry_types.' + editor.entryType.name + '.editor.entry_metadata_configuration_attributes']
|
4991
5305
|
});
|
4992
5306
|
configurationEditor.tab('general', function () {
|
4993
5307
|
this.input('title', TextInputView, {
|
@@ -5020,7 +5334,10 @@ var EditMetaDataView = Marionette.Layout.extend({
|
|
5020
5334
|
});
|
5021
5335
|
});
|
5022
5336
|
configurationEditor.tab('widgets', function () {
|
5023
|
-
editor.entryType.appearanceInputs && editor.entryType.appearanceInputs(this,
|
5337
|
+
editor.entryType.appearanceInputs && editor.entryType.appearanceInputs(this, {
|
5338
|
+
entry: entry,
|
5339
|
+
theming: state.theming
|
5340
|
+
});
|
5024
5341
|
entry.widgets && this.view(EditWidgetsView, {
|
5025
5342
|
model: entry,
|
5026
5343
|
widgetTypes: editor.widgetTypes
|
@@ -5329,28 +5646,12 @@ var EditWidgetView = Marionette.ItemView.extend({
|
|
5329
5646
|
}
|
5330
5647
|
});
|
5331
5648
|
|
5332
|
-
var loadable = {
|
5333
|
-
|
5334
|
-
|
5335
|
-
|
5336
|
-
},
|
5337
|
-
destroying: function destroying() {
|
5338
|
-
this.$el.addClass('destroying');
|
5339
|
-
},
|
5340
|
-
error: function error() {
|
5341
|
-
this.$el.removeClass('destroying');
|
5342
|
-
}
|
5343
|
-
},
|
5344
|
-
render: function render() {
|
5345
|
-
if (this.model.isNew()) {
|
5346
|
-
this.$el.addClass('creating');
|
5347
|
-
}
|
5348
|
-
|
5349
|
-
if (this.model.isDestroying && this.model.isDestroying()) {
|
5350
|
-
this.$el.addClass('destroying');
|
5351
|
-
}
|
5649
|
+
var loadable = modelLifecycleTrackingView({
|
5650
|
+
classNames: {
|
5651
|
+
creating: 'creating',
|
5652
|
+
destroying: 'destroying'
|
5352
5653
|
}
|
5353
|
-
};
|
5654
|
+
});
|
5354
5655
|
|
5355
5656
|
function template$r(data) {
|
5356
5657
|
var __p = '';
|
@@ -7467,8 +7768,8 @@ var NotificationsView = Marionette.ItemView.extend({
|
|
7467
7768
|
onRender: function onRender() {
|
7468
7769
|
this.listenTo(state.entry, 'change:uploading_files_count', this.notifyUploadCount);
|
7469
7770
|
this.listenTo(state.entry, 'change:confirmable_files_count', this.notifyConfirmableFilesCount);
|
7470
|
-
this.listenTo(
|
7471
|
-
this.listenTo(
|
7771
|
+
this.listenTo(editor$1.savingRecords, 'add', this.update);
|
7772
|
+
this.listenTo(editor$1.savingRecords, 'remove', this.update);
|
7472
7773
|
this.listenTo(editor$1.failures, 'add', this.update);
|
7473
7774
|
this.listenTo(editor$1.failures, 'remove', this.update);
|
7474
7775
|
this.update();
|
@@ -7476,7 +7777,7 @@ var NotificationsView = Marionette.ItemView.extend({
|
|
7476
7777
|
},
|
7477
7778
|
update: function update() {
|
7478
7779
|
this.$el.toggleClass('failed', !editor$1.failures.isEmpty());
|
7479
|
-
this.$el.toggleClass('saving', !
|
7780
|
+
this.$el.toggleClass('saving', !editor$1.savingRecords.isEmpty());
|
7480
7781
|
this.ui.failedCount.text(editor$1.failures.count());
|
7481
7782
|
},
|
7482
7783
|
notifyUploadCount: function notifyUploadCount(model, uploadCount) {
|
@@ -7855,6 +8156,101 @@ ConfirmUploadView.open = function (options) {
|
|
7855
8156
|
app.dialogRegion.show(new ConfirmUploadView(options));
|
7856
8157
|
};
|
7857
8158
|
|
8159
|
+
/**
|
8160
|
+
* Base view to edit configuration container models. Extend and
|
8161
|
+
* override the `configure` method which receives a {@link
|
8162
|
+
* ConfigurationEditorView} to define the tabs and inputs that shall
|
8163
|
+
* be displayed.
|
8164
|
+
*
|
8165
|
+
* Add a `translationKeyPrefix` property to the prototype and define
|
8166
|
+
* the following translations:
|
8167
|
+
*
|
8168
|
+
* * `<translationKeyPrefix>.tabs`: used as `tabTranslationKeyPrefix`
|
8169
|
+
* of the `ConfigurationEditorView`.
|
8170
|
+
*
|
8171
|
+
* * `<translationKeyPrefix>.attributes`: used as one of the
|
8172
|
+
* `attributeTranslationKeyPrefixes` of the
|
8173
|
+
* `ConfigurationEditorView`.
|
8174
|
+
*
|
8175
|
+
* * `<translationKeyPrefix>.back` (optional): Back button label.
|
8176
|
+
*
|
8177
|
+
* * `<translationKeyPrefix>.destroy` (optional): Destroy button
|
8178
|
+
* label.
|
8179
|
+
*
|
8180
|
+
* * `<translationKeyPrefix>.confirm_destroy` (optional): Confirm
|
8181
|
+
* message displayed before destroying.
|
8182
|
+
*
|
8183
|
+
* * `<translationKeyPrefix>.save_error` (optional): Header of the
|
8184
|
+
* failure message that is displayed if the model cannot be saved.
|
8185
|
+
*
|
8186
|
+
* * `<translationKeyPrefix>.retry` (optional): Label of the retry
|
8187
|
+
* button of the failure message.
|
8188
|
+
*
|
8189
|
+
* @param {Object} options
|
8190
|
+
* @param {Backbone.Model} options.model -
|
8191
|
+
* Model including the {@link configurationContainer},
|
8192
|
+
* {@link failureTracking} and {@link delayedDestroying} mixins.
|
8193
|
+
*
|
8194
|
+
* @since edge
|
8195
|
+
*/
|
8196
|
+
|
8197
|
+
var EditConfigurationView = Marionette.Layout.extend({
|
8198
|
+
className: 'edit_configuration_view',
|
8199
|
+
template: function template(_ref) {
|
8200
|
+
var t = _ref.t;
|
8201
|
+
return "\n <a class=\"back\">".concat(t('back'), "</a>\n <a class=\"destroy\">").concat(t('destroy'), "</a>\n\n <div class=\"failure\">\n <p>").concat(t('save_error'), "</p>\n <p class=\"message\"></p>\n <a class=\"retry\" href=\"\">").concat(t('retry'), "</a>\n </div>\n\n <div class=\"configuration_container\"></div>\n ");
|
8202
|
+
},
|
8203
|
+
serializeData: function serializeData() {
|
8204
|
+
var _this = this;
|
8205
|
+
|
8206
|
+
return {
|
8207
|
+
t: function t(key) {
|
8208
|
+
return _this.t(key);
|
8209
|
+
}
|
8210
|
+
};
|
8211
|
+
},
|
8212
|
+
mixins: [failureIndicatingView],
|
8213
|
+
regions: {
|
8214
|
+
configurationContainer: '.configuration_container'
|
8215
|
+
},
|
8216
|
+
events: {
|
8217
|
+
'click a.back': 'goBack',
|
8218
|
+
'click a.destroy': 'destroy'
|
8219
|
+
},
|
8220
|
+
onRender: function onRender() {
|
8221
|
+
var translationKeyPrefix = _$1.result(this, 'translationKeyPrefix');
|
8222
|
+
|
8223
|
+
this.configurationEditor = new ConfigurationEditorView({
|
8224
|
+
tabTranslationKeyPrefix: "".concat(translationKeyPrefix, ".tabs"),
|
8225
|
+
attributeTranslationKeyPrefixes: ["".concat(translationKeyPrefix, ".attributes")],
|
8226
|
+
model: this.model.configuration
|
8227
|
+
});
|
8228
|
+
this.configure(this.configurationEditor);
|
8229
|
+
this.configurationContainer.show(this.configurationEditor);
|
8230
|
+
},
|
8231
|
+
onShow: function onShow() {
|
8232
|
+
this.configurationEditor.refreshScroller();
|
8233
|
+
},
|
8234
|
+
destroy: function destroy() {
|
8235
|
+
if (window.confirm(this.t('confirm_destroy'))) {
|
8236
|
+
this.model.destroyWithDelay();
|
8237
|
+
this.goBack();
|
8238
|
+
}
|
8239
|
+
},
|
8240
|
+
goBack: function goBack() {
|
8241
|
+
editor$1.navigate('/', {
|
8242
|
+
trigger: true
|
8243
|
+
});
|
8244
|
+
},
|
8245
|
+
t: function t(suffix) {
|
8246
|
+
var translationKeyPrefix = _$1.result(this, 'translationKeyPrefix');
|
8247
|
+
|
8248
|
+
return I18n$1.t("".concat(translationKeyPrefix, ".").concat(suffix), {
|
8249
|
+
defaultValue: I18n$1.t("pageflow.editor.views.edit_configuration.".concat(suffix))
|
8250
|
+
});
|
8251
|
+
}
|
8252
|
+
});
|
8253
|
+
|
7858
8254
|
ConfigurationEditorView.register('audio', {
|
7859
8255
|
configure: function configure() {
|
7860
8256
|
this.tab('general', function () {
|
@@ -8360,9 +8756,8 @@ app.addInitializer(function (options) {
|
|
8360
8756
|
editor$1.failures.watch(state.entry);
|
8361
8757
|
editor$1.failures.watch(state.pages);
|
8362
8758
|
editor$1.failures.watch(state.chapters);
|
8363
|
-
|
8364
|
-
|
8365
|
-
state.savingRecords.watch(state.chapters);
|
8759
|
+
editor$1.savingRecords.watch(state.pages);
|
8760
|
+
editor$1.savingRecords.watch(state.chapters);
|
8366
8761
|
pageflow.events.trigger('seed:loaded');
|
8367
8762
|
});
|
8368
8763
|
|
@@ -8498,4 +8893,4 @@ app.addRegions({
|
|
8498
8893
|
sidebarFooterRegion: 'sidebar .sidebar_footer_container'
|
8499
8894
|
});
|
8500
8895
|
|
8501
|
-
export { AudioFile, BackButtonDecoratorView, BackgroundImageEmbeddedView, BackgroundPositioningPreviewView, BackgroundPositioningSlidersView, BackgroundPositioningView, ChangeThemeDialogView, Chapter, ChapterConfiguration, ChapterPagesCollection, ChapterScaffold, ChaptersCollection, ChooseImporterView, Configuration, ConfirmEncodingView, ConfirmFileImportUploadView, ConfirmUploadView, ConfirmableFileItemView, DisabledAtmoIndicatorView, DropDownButtonItemListView, DropDownButtonItemView, DropDownButtonView, EditChapterView, EditEntryView, EditFileView, EditLock, EditLockContainer, EditMetaDataView, EditPageLinkView, EditPageView, EditStorylineView, EditWidgetView, EditWidgetsView, EditorApi, EditorView, EmulationModeButtonView, EncodedFile, EncodingConfirmation, Entry, EntryMetadata, EntryMetadataFileSelectionHandler, EntryPublication, EntryPublicationQuotaDecoratorView, ExplorerFileItemView, FileConfiguration, FileImport, FileInputView, FileItemView, FileMetaDataItemValueView, FileMetaDataItemView, FileProcessingStateDisplayView, FileReuse, FileSettingsDialogView, FileStage, FileStageItemView, FileThumbnailView, FileTypes, FileTypesCollection, FileUploader, FilesCollection, FilesExplorerView, FilesImporterView, FilesView, FilteredFilesView, HelpButtonView, HelpImageView, HelpView, ImageFile, InfoBoxView, InvalidNestedTypeError, LazyVideoEmbeddedView, ListItemView, ListView, LoadingView, LockedView, ModelThumbnailView,
|
8896
|
+
export { AudioFile, BackButtonDecoratorView, BackgroundImageEmbeddedView, BackgroundPositioningPreviewView, BackgroundPositioningSlidersView, BackgroundPositioningView, ChangeThemeDialogView, Chapter, ChapterConfiguration, ChapterPagesCollection, ChapterScaffold, ChaptersCollection, ChooseImporterView, Configuration, ConfirmEncodingView, ConfirmFileImportUploadView, ConfirmUploadView, ConfirmableFileItemView, DisabledAtmoIndicatorView, DropDownButtonItemListView, DropDownButtonItemView, DropDownButtonView, EditChapterView, EditConfigurationView, EditEntryView, EditFileView, EditLock, EditLockContainer, EditMetaDataView, EditPageLinkView, EditPageView, EditStorylineView, EditWidgetView, EditWidgetsView, EditorApi, EditorView, EmulationModeButtonView, EncodedFile, EncodingConfirmation, Entry, EntryMetadata, EntryMetadataFileSelectionHandler, EntryPublication, EntryPublicationQuotaDecoratorView, ExplorerFileItemView, Failure, FileConfiguration, FileImport, FileInputView, FileItemView, FileMetaDataItemValueView, FileMetaDataItemView, FileProcessingStateDisplayView, FileReuse, FileSettingsDialogView, FileStage, FileStageItemView, FileThumbnailView, FileTypes, FileTypesCollection, FileUploader, FilesCollection, FilesExplorerView, FilesImporterView, FilesView, FilteredFilesView, ForeignKeySubsetCollection, HelpButtonView, HelpImageView, HelpView, ImageFile, InfoBoxView, InvalidNestedTypeError, LazyVideoEmbeddedView, ListItemView, ListView, LoadingView, LockedView, ModelThumbnailView, NestedFilesCollection, NestedFilesView, NestedTypeError, NotificationsView, OrderedPageLinksCollection, OtherEntriesCollection, OtherEntriesCollectionView, OtherEntry, OtherEntryItemView, Page, PageConfigurationFileSelectionHandler, PageLink, PageLinkConfigurationEditorView, PageLinkFileSelectionHandler, PageLinkInputView, PageLinkItemView, PageLinksCollection, PageLinksView, PageThumbnailView, PagesCollection, PreviewEntryData, PublishEntryView, ReferenceInputView, ReusableFile, Scaffold, ScrollingView, SelectButtonView, SidebarController, SidebarFooterView, SidebarRouter, StaticThumbnailView, Storyline, StorylineChaptersCollection, StorylineConfiguration, StorylineOrdering, StorylineScaffold, StorylineTransitiveChildPages, StorylinesCollection, SubsetCollection, TextFileMetaDataItemValueView, TextTrackFile, TextTracksFileMetaDataItemValueView, TextTracksView, Theme, ThemeInputView, ThemeItemView, ThemesCollection, Theming, UnmatchedUploadError, UploadError, UploadableFile, UploadableFilesView, UploaderView, VideoFile, Widget, WidgetConfiguration, WidgetConfigurationFileSelectionHandler, WidgetItemView, WidgetTypes, WidgetsCollection, addAndReturnModel, app, authenticationProvider, configurationContainer, delayedDestroying, dialogView, editor$1 as editor, entryTypeEditorControllerUrls, failureIndicatingView, failureTracking, fileWithType, filesCountWatcher, formDataUtils, loadable, modelLifecycleTrackingView, orderedCollection, persistedPromise, polling, retryable, selectableView, stageProvider, startEditor, state, stylesheet, transientReferences, validFileTypeTranslationList };
|