app/assets/javascripts/pageflow/dist/editor.js in pageflow-15.1.0.beta2 vs app/assets/javascripts/pageflow/dist/editor.js in pageflow-15.1.0.beta3
- old
+ new
@@ -23,10 +23,25 @@
return sync(method, model, options);
};
})();
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
/*global JST*/
Marionette.Renderer.render = function (template, data) {
if (_$1.isFunction(template)) {
return template(data);
@@ -40,18 +55,11 @@
throw "Template '" + template + "' not found!";
}
return JST[template](data);
};
-
/**
- * Helpers functions for handling translations.
- *
- * @memberof module:pageflow/ui
- */
-
- /**
* Returns an array of translation keys based on the `prefixes`
* option and the given `keyName`.
*
* @param {string} keyName
* Suffix to append to prefixes.
@@ -66,13 +74,15 @@
*
* @param {string} [options.fallbackModelI18nKey]
* Required if `fallbackPrefix` option is present.
*
* @return {string[]}
+ * @memberof i18nUtils
* @since 12.0
- */
+ */
+
function attributeTranslationKeys(attributeName, keyName, options) {
var result = [];
if (options.prefixes) {
result = result.concat(_$1(options.prefixes).map(function (prefix) {
@@ -86,18 +96,19 @@
return result;
}
/**
* Takes the same parameters as {@link
- * module:pageflow/ui.attributeTranslationKeys
- * i18nUtils.attributeTranslationKeys}, but returns the first
- * existing translation.
+ * #i18nutilsattributetranslationkeys attributeTranslationKeys}, but returns the first existing
+ * translation.
*
* @return {string}
+ * @memberof i18nUtils
* @since 12.0
*/
+
function attributeTranslation(attributeName, keyName, options) {
return findTranslation(attributeTranslationKeys(attributeName, keyName, options));
}
/**
* Find the first key for which a translation exists and return the
@@ -112,13 +123,15 @@
*
* @param {boolean} [options.html]
* If true, also search for keys ending in '_html' and HTML-escape
* keys that do not end in 'html'
*
+ * @memberof i18nUtils
* @return {string}
*/
+
function findTranslation(keys, options) {
options = options || {};
if (options.html) {
keys = translationKeysWithSuffix(keys, 'html');
@@ -141,49 +154,226 @@
* first if non of the keys has a translation.
*
* @param {string[]} keys
* Translation key candidates.
*
+ * @memberof i18nUtils
* @return {string}
*/
+
function findKeyWithTranslation(keys) {
var missing = '_not_translated';
return _$1(keys).detect(function (key) {
return I18n$1.t(key, {
defaultValue: missing
}) !== missing;
}) || _$1.first(keys);
}
+
function translationKeysWithSuffix(keys, suffix) {
return _$1.chain(keys).map(function (key) {
return [key + '_' + suffix, key];
}).flatten().value();
}
- var i18nUtils = /*#__PURE__*/Object.freeze({
+ var i18nUtils =
+ /*#__PURE__*/
+ Object.freeze({
__proto__: null,
attributeTranslationKeys: attributeTranslationKeys,
attributeTranslation: attributeTranslation,
findTranslation: findTranslation,
findKeyWithTranslation: findKeyWithTranslation,
translationKeysWithSuffix: translationKeysWithSuffix
});
- // https://github.com/jashkenas/backbone/issues/2601
+ function _arrayWithHoles(arr) {
+ if (Array.isArray(arr)) return arr;
+ }
+ function _iterableToArrayLimit(arr, i) {
+ if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) {
+ return;
+ }
+
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+ var _e = undefined;
+
+ try {
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
+ _arr.push(_s.value);
+
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i["return"] != null) _i["return"]();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+
+ return _arr;
+ }
+
+ function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance");
+ }
+
+ function _slicedToArray(arr, i) {
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
+ }
+ /**
+ * Create object that can be passed to Marionette ui property from CSS
+ * module object.
+ *
+ * @param {Object} styles
+ * Class name mapping imported from `.module.css` file.
+ *
+ * @param {...string} classNames
+ * Keys from the styles object that shall be used in the ui object.
+ *
+ * @return {Object}
+ *
+ * @example
+ *
+ * // MyView.module.css
+ *
+ * .container {}
+ *
+ * // MyView.js
+ *
+ * import Marionette from 'marionette';
+ * import {cssModulesUtils} from 'pageflow/ui';
+ *
+ * import styles from './MyView.module.css';
+ *
+ * export const MyView = Marionette.ItemView({
+ * template: () => `
+ * <div class=${styles.container}></div>
+ * `,
+ *
+ * ui: cssModulesUtils.ui(styles, 'container'),
+ *
+ * onRender() {
+ * this.ui.container // => JQuery wrapper for container element
+ * }
+ * });
+ *
+ * @memberof cssModulesUtils
+ */
+
+
+ function ui(styles) {
+ for (var _len = arguments.length, classNames = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ classNames[_key - 1] = arguments[_key];
+ }
+
+ return classNames.reduce(function (result, className) {
+ result[className] = selector(styles, className);
+ return result;
+ }, {});
+ }
+ /**
+ * Create object that can be passed to Marionette events property from CSS
+ * module object.
+ *
+ * @param {Object} styles
+ * Class name mapping imported from `.module.css` file.
+ *
+ * @param {Object} mapping
+ * Events mapping using keys from the `styles` instead of CSS class names.
+ *
+ * @return {Object}
+ *
+ * @example
+ *
+ * // MyView.module.css
+ *
+ * .addButton {}
+ *
+ * // MyView.js
+ *
+ * import Marionette from 'marionette';
+ * import {cssModulesUtils} from 'pageflow/ui';
+ *
+ * import styles from './MyView.module.css';
+ *
+ * export const MyView = Marionette.ItemView({
+ * template: () => `
+ * <button class=${styles.addButton}></button>
+ * `,
+ *
+ * events: cssModulesUtils.ui(styles, {
+ * 'click addButton': () => console.log('clicked add button');
+ * })
+ * });
+ *
+ * @memberof cssModulesUtils
+ */
+
+
+ function events(styles, mapping) {
+ return Object.keys(mapping).reduce(function (result, key) {
+ var _key$split = key.split(' '),
+ _key$split2 = _slicedToArray(_key$split, 2),
+ event = _key$split2[0],
+ className = _key$split2[1];
+
+ result["".concat(event, " ").concat(selector(styles, className))] = mapping[key];
+ return result;
+ }, {});
+ }
+ /**
+ * Generates a CSS selector from a CSS module rule.
+ *
+ * @param {Object} styles
+ * Class name mapping imported from `.module.css` file.
+ *
+ * @param {String} className
+ * Key from the `styles` object.
+ *
+ * @return {String} CSS Selector
+ * @memberof cssModulesUtils
+ */
+
+
+ function selector(styles, className) {
+ var classNames = styles[className];
+
+ if (!classNames) {
+ throw new Error("Unknown class name ".concat(className, " in mapping. Knwon names: ").concat(Object.keys(styles).join(', '), "."));
+ }
+
+ return ".".concat(classNames.replace(/ /g, '.'));
+ }
+
+ var cssModulesUtils =
+ /*#__PURE__*/
+ Object.freeze({
+ __proto__: null,
+ ui: ui,
+ events: events,
+ selector: selector
+ }); // https://github.com/jashkenas/backbone/issues/2601
+
function BaseObject(options) {
this.initialize.apply(this, arguments);
}
_$1.extend(BaseObject.prototype, Backbone.Events, {
initialize: function initialize(options) {}
}); // The self-propagating extend function that Backbone classes use.
BaseObject.extend = Backbone.Model.extend;
-
var CollectionView = Marionette.View.extend({
initialize: function initialize() {
this.rendered = false;
this.itemViews = new ChildViewContainer();
this.collection.map(this.addItem, this);
@@ -299,11 +489,10 @@
} else if (this.options.blankSlateViewConstructor) {
return this.options.blankSlateViewConstructor;
}
}
});
-
var SortableCollectionView = CollectionView.extend({
render: function render() {
CollectionView.prototype.render.call(this);
this.$el.sortable({
connectWith: this.options.connectWith,
@@ -348,11 +537,10 @@
this.$el.children().each(function (index) {
$(this).data('view').model.set('position', index);
});
}
});
-
var ConfigurationEditorTabView = Marionette.View.extend({
className: 'configuration_editor_tab',
initialize: function initialize() {
this.inputs = new ChildViewContainer();
this.groups = this.options.groups || ConfigurationEditorTabView.groups;
@@ -407,19 +595,21 @@
};
ConfigurationEditorTabView.groups = new ConfigurationEditorTabView.Groups();
function template(data) {
- var __p = '';
- __p += '<div class="tabs_view-scroller">\n <ul class="tabs_view-headers"></ul>\n</div>\n<div class="tabs_view-container"></div>\n';
- return __p
+ var __p = '';
+ __p += '<div class="tabs_view-scroller">\n <ul class="tabs_view-headers"></ul>\n</div>\n<div class="tabs_view-container"></div>\n';
+ return __p;
}
-
/*global pageflow*/
+
/**
* Switch between different views using tabs.
*
+ * @param {Object} [options]
+ *
* @param {string} [options.defaultTab]
* Name of the tab to enable by default.
*
* @param {string[]} [options.translationKeyPrefixes]
* List of prefixes to append tab name to. First exisiting translation is used as label.
@@ -430,14 +620,16 @@
*
* @param {string} [options.i18n]
* Legacy alias for `fallbackTranslationKeyPrefix`.
*
* @class
- * @memberof module:pageflow/ui
*/
- var TabsView = Marionette.Layout.extend({
+
+ var TabsView = Marionette.Layout.extend(
+ /* @lends TabView.prototype */
+ {
template: template,
className: 'tabs_view',
ui: {
headers: '.tabs_view-headers',
scroller: '.tabs_view-scroller'
@@ -539,14 +731,15 @@
this.scroller.refresh();
});
}
}
});
-
/**
* Render a inputs on multiple tabs.
*
+ * @param {Object} [options]
+ *
* @param {string} [options.model]
* Backbone model to use for input views.
*
* @param {string} [options.placeholderModel]
* Backbone model to read placeholder values from.
@@ -562,11 +755,10 @@
*
* @param {string} [options.tabTranslationKeyPrefix]
* Prefixes to append tab name to.
*
* @class
- * @memberof module:pageflow/ui
*/
var ConfigurationEditorView = Marionette.View.extend({
className: 'configuration_editor',
initialize: function initialize() {
@@ -616,28 +808,30 @@
this.repository[pageTypeName] = ConfigurationEditorView.extend(prototype);
}
});
function template$1(data) {
- var __p = '';
- __p += '';
- return __p
+ var __p = '';
+ __p += '';
+ return __p;
}
-
/**
* Base class for table cell views.
*
* Inside sub classes the name of the column options are available as
* `this.options.column`. Override the `update` method to populate the
* element.
*
+ * @param {Object} [options]
+ *
* @param {string} [options.className]
* Class attribute to apply to the cell element.
*
* @since 12.0
*/
+
var TableCellView = Marionette.ItemView.extend({
tagName: 'td',
template: template$1,
className: function className() {
return this.options.className;
@@ -714,20 +908,18 @@
this.listenTo(this.getModel(), 'change:' + this.options.column.contentBinding, this.update);
this.update();
}
}
});
-
var TableHeaderCellView = TableCellView.extend({
tagName: 'th',
render: function render() {
this.$el.text(this.attributeTranslation('column_header'));
this.$el.data('columnName', this.options.column.name);
return this;
}
});
-
var TableRowView = Marionette.View.extend({
tagName: 'tr',
events: {
'click': function click() {
if (this.options.selection) {
@@ -762,23 +954,21 @@
return this.options.selectionAttribute || 'current';
}
});
function template$2(data) {
- var __p = '';
- __p += '<table>\n <thead>\n <tr></tr>\n </thead>\n <tbody>\n </tbody>\n</table>\n';
- return __p
+ var __p = '';
+ __p += '<table>\n <thead>\n <tr></tr>\n </thead>\n <tbody>\n </tbody>\n</table>\n';
+ return __p;
}
function blankSlateTemplate(data) {
- var __t, __p = '';
- __p += '<td colspan="' +
- ((__t = ( data.colSpan )) == null ? '' : __t) +
- '">\n ' +
- ((__t = ( data.blankSlateText )) == null ? '' : __t) +
- '\n</td>\n';
- return __p
+ var __t,
+ __p = '';
+
+ __p += '<td colspan="' + ((__t = data.colSpan) == null ? '' : __t) + '">\n ' + ((__t = data.blankSlateText) == null ? '' : __t) + '\n</td>\n';
+ return __p;
}
var TableView = Marionette.ItemView.extend({
tagName: 'table',
className: 'table_view',
@@ -821,13 +1011,13 @@
}));
}
});
function template$3(data) {
- var __p = '';
- __p += '<span class="label">\n</span>\n';
- return __p
+ var __p = '';
+ __p += '<span class="label">\n</span>\n';
+ return __p;
}
var TooltipView = Marionette.ItemView.extend({
template: template$3,
className: 'tooltip',
@@ -864,11 +1054,10 @@
});
this.$el.addClass('visible');
}, this), 200);
}
});
-
/**
* Mixin for input views handling common concerns like labels,
* inline help, visiblity and disabling.
*
* ## Label and Inline Help Translations
@@ -975,11 +1164,10 @@
* @param {any} [options.visibleBindingValue]
* Input will be visible whenever the value of the `visibleBinding`
* attribute equals the value of this option.
*
* @mixin
- * @memberof module:pageflow/ui
*/
var inputView = {
ui: {
labelText: 'label .name',
@@ -988,17 +1176,16 @@
/**
* Returns an array of translation keys based on the
* `attributeTranslationKeyPrefixes` option and the given keyName.
*
- * Combined with {@link
- * module:pageflow/ui.findTranslation
+ * Combined with {@link #i18nutils
* i18nUtils.findTranslation}, this can be used inside input views
* to obtain additional translations with the same logic as for
* labels and inline help texts.
*
- * findTranslation(this.attributeTranslationKeys('default_value'));
+ * findTranslation(this.attributeTranslationKeys('default_value'));
*
* @param {string} keyName
* Suffix to append to prefixes.
*
* @param {string} [options.fallbackPrefix]
@@ -1098,23 +1285,24 @@
}
}
};
function template$4(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="check_boxes_container" />\n';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="check_boxes_container" />\n';
+ return __p;
}
-
/**
* Input view for attributes storing configuration hashes with boolean values.
+ * See {@link inputView} for further options.
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
+ * @param {Object} [options]
+ *
* @class
- * @memberof module:pageflow/ui
*/
+
var CheckBoxGroupInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$4,
className: 'check_box_group_input',
events: {
@@ -1169,28 +1357,29 @@
}
}
});
function template$5(data) {
- var __t, __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<a class="original" href="#" download target="_blank">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.url_display.link_text') )) == null ? '' : __t) +
- '\n</a>\n';
- return __p
- }
+ var __t,
+ __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<a class="original" href="#" download target="_blank">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.url_display.link_text')) == null ? '' : __t) + '\n</a>\n';
+ return __p;
+ }
/**
* Display view for a link to a URL, to be used like an input view.
+ * See {@link inputView} for further options
*
+ * @param {Object} [options]
+ *
* @param {string} [options.propertyName]
* Target URL for link
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var UrlDisplayView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$5,
ui: {
link: 'a'
@@ -1211,14 +1400,15 @@
var url = this.model.get('original_url');
this.$el.toggle(this.model.isUploaded() && !_$1.isEmpty(url));
this.ui.link.attr('href', url);
}
});
-
/**
* Text based input view that can display a placeholder.
*
+ * @param {Object} [options]
+ *
* @param {string|function} [options.placeholder]
* Display a placeholder string if the input is blank. Either a
* string or a function taking the model as a first parameter and
* returning a string.
*
@@ -1230,14 +1420,12 @@
* Do not display the placeholder if the input is disabled.
*
* @param {Backbone.Model} [options.placeholderModel]
* Obtain placeholder by looking up the configured `propertyName`
* inside a given model.
- *
- * @mixin
- * @memberof module:pageflow/ui
*/
+
var inputWithPlaceholderText = {
onRender: function onRender() {
this.updatePlaceholder();
if (this.options.placeholderBinding) {
@@ -1264,35 +1452,35 @@
return this.options.placeholderModel && this.options.placeholderModel.get(this.options.propertyName);
}
};
function template$6(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" dir="auto" />\n';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" dir="auto" />\n';
+ return __p;
}
-
/**
* Input view for a single line of text.
*
+ * See {@link inputWithPlaceholderText} for placeholder related
+ * further options. See {@link inputView} for further options.
+ *
+ * @param {Object} [options]
+ *
* @param {boolean} [options.required=false]
- * Display an error if the input is blank.
+ * Display an error if the input is blank.
*
* @param {number} [options.maxLength=255]
- * Maximum length of characters for this input.
- * To support legacy data which consists of more characters than the specified maxLength,
- * the option will only take effect for data which is shorter than the specified maxLength.
+ * Maximum length of characters for this input. To support legacy
+ * data which consists of more characters than the specified
+ * maxLength, the option will only take effect for data which is
+ * shorter than the specified maxLength.
*
- * @see
- * {@link module:pageflow/ui.inputWithPlaceholderText inputWithPlaceholderText}
- * for placeholder related further options
- *
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var TextInputView = Marionette.ItemView.extend({
mixins: [inputView, inputWithPlaceholderText],
template: template$6,
ui: {
input: 'input'
@@ -1352,14 +1540,16 @@
resetValidationError: function resetValidationError(message) {
this.$el.removeClass('invalid');
this.ui.input.attr('title', '');
}
});
-
/**
* Input view for a color value in hex representation.
+ * See {@link inputView} for further options
*
+ * @param {Object} [options]
+ *
* @param {string|function} [options.defaultValue]
* Color value to display by default. The corresponding value is not
* stored in the model. Selecting the default value when a different
* value was set before, unsets the attribute in the model.
*
@@ -1373,13 +1563,11 @@
* @param {string[]} [options.swatches]
* Preset color values to be displayed inside the picker drop
* down. The default value, if present, is always used as the
* first swatch automatically.
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
var ColorInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$6,
@@ -1442,18 +1630,20 @@
}
}
});
function template$7(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<select></select>';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<select></select>';
+ return __p;
}
-
/**
* A drop down with support for grouped items.
+ * See {@link inputView} for further options
*
+ * @param {Object} [options]
+ *
* @param {string[]} [options.values]
* List of possible values to persist in the attribute.
*
* @param {string[]} [options.texts]
* List of display texts for drop down items.
@@ -1462,11 +1652,11 @@
* Translation keys to obtain item texts from.
*
* @param {string[]} [options.translationKeyPrefix]
* Obtain texts for items from translations by appending the item
* value to this prefix separated by a dot. By default the
- * [`attributeTranslationKeyPrefixes` option]{@link module:pageflow/ui:inputView}
+ * [`attributeTranslationKeyPrefixes` option]{@link inputView}
* is used by appending the suffix `.values` to each candidate.
*
* @param {string[]} [options.groups]
* Array of same length as `values` array, containing the display
* name of a group header each item shall be grouped under.
@@ -1516,15 +1706,14 @@
* up the `propertyName` attribute inside the given model. This
* option can be used if a fallback to the corresponding attribute
* value of the `placeholderModel` occurs whenever the attribute is
* blank.
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var SelectInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$7,
events: {
'change': 'save'
@@ -1652,11 +1841,10 @@
this.ui.select.val(this.ui.select.find('option:first').val());
}
}
}
});
-
var ExtendedSelectInputView = SelectInputView.extend({
className: 'extended_select_input',
initialize: function initialize() {
SelectInputView.prototype.initialize.apply(this, arguments);
@@ -1753,46 +1941,23 @@
this.save();
}
});
function template$8(data) {
- var __t, __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<!-- inline style for wysihtml5 to pick up -->\n<textarea style="width: 100%;" dir="auto"></textarea>\n\n<div class="toolbar">\n <a data-wysihtml5-command="bold" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.bold') )) == null ? '' : __t) +
- '"></a>\n <a data-wysihtml5-command="italic" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.italic') )) == null ? '' : __t) +
- '"></a>\n <a data-wysihtml5-command="underline" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.underline') )) == null ? '' : __t) +
- '"></a>\n <a data-wysihtml5-command="createLink" class="link_button" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.create_link') )) == null ? '' : __t) +
- '"></a>\n <a data-wysihtml5-command="insertOrderedList" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.insert_ordered_list') )) == null ? '' : __t) +
- '"></a>\n <a data-wysihtml5-command="insertUnorderedList" title="' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.insert_unordered_list') )) == null ? '' : __t) +
- '"></a>\n\n <div data-wysihtml5-dialog="createLink" class="dialog link_dialog" style="display: none;">\n <div class="link_type_select">\n <label>\n <input type="radio" name="link_type" class="url_link_radio_button">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.link_type.url') )) == null ? '' : __t) +
- '\n </label>\n <label>\n <input type="radio" name="link_type" class="fragment_link_radio_button">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.link_type.page_link') )) == null ? '' : __t) +
- '\n </label>\n </div>\n <div class="url_link_panel">\n <label>\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.target') )) == null ? '' : __t) +
- '\n </label>\n <input type="text" class="display_url">\n <div class="open_in_new_tab_section">\n <label>\n <input type="checkbox" class="open_in_new_tab">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.open_in_new_tab') )) == null ? '' : __t) +
- '\n </label>\n <span class="inline_help">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.open_in_new_tab_help') )) == null ? '' : __t) +
- '\n </span>\n </div>\n </div>\n <div class="fragment_link_panel">\n <!-- LinkInputView is inserted here -->\n </div>\n\n <!-- wysihtml5 does not handle hidden fields correctly -->\n <div class="internal">\n <input type="text" data-wysihtml5-dialog-field="href" class="current_url" value="http://">\n <input type="text" data-wysihtml5-dialog-field="target" class="current_target" value="_blank">\n </div>\n\n <a class="button" data-wysihtml5-dialog-action="save">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.save') )) == null ? '' : __t) +
- '\n </a>\n <a class="button" data-wysihtml5-dialog-action="cancel">\n ' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.cancel') )) == null ? '' : __t) +
- '\n </a>\n\n <a data-wysihtml5-command="removeLink">' +
- ((__t = ( I18n.t('pageflow.ui.templates.inputs.text_area_input.remove_link') )) == null ? '' : __t) +
- '</a>\n </div>\n</div>\n';
- return __p
- }
+ var __t,
+ __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<!-- inline style for wysihtml5 to pick up -->\n<textarea style="width: 100%;" dir="auto"></textarea>\n\n<div class="toolbar">\n <a data-wysihtml5-command="bold" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.bold')) == null ? '' : __t) + '"></a>\n <a data-wysihtml5-command="italic" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.italic')) == null ? '' : __t) + '"></a>\n <a data-wysihtml5-command="underline" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.underline')) == null ? '' : __t) + '"></a>\n <a data-wysihtml5-command="createLink" class="link_button" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.create_link')) == null ? '' : __t) + '"></a>\n <a data-wysihtml5-command="insertOrderedList" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.insert_ordered_list')) == null ? '' : __t) + '"></a>\n <a data-wysihtml5-command="insertUnorderedList" title="' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.insert_unordered_list')) == null ? '' : __t) + '"></a>\n\n <div data-wysihtml5-dialog="createLink" class="dialog link_dialog" style="display: none;">\n <div class="link_type_select">\n <label>\n <input type="radio" name="link_type" class="url_link_radio_button">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.link_type.url')) == null ? '' : __t) + '\n </label>\n <label>\n <input type="radio" name="link_type" class="fragment_link_radio_button">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.link_type.page_link')) == null ? '' : __t) + '\n </label>\n </div>\n <div class="url_link_panel">\n <label>\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.target')) == null ? '' : __t) + '\n </label>\n <input type="text" class="display_url">\n <div class="open_in_new_tab_section">\n <label>\n <input type="checkbox" class="open_in_new_tab">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.open_in_new_tab')) == null ? '' : __t) + '\n </label>\n <span class="inline_help">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.open_in_new_tab_help')) == null ? '' : __t) + '\n </span>\n </div>\n </div>\n <div class="fragment_link_panel">\n <!-- LinkInputView is inserted here -->\n </div>\n\n <!-- wysihtml5 does not handle hidden fields correctly -->\n <div class="internal">\n <input type="text" data-wysihtml5-dialog-field="href" class="current_url" value="http://">\n <input type="text" data-wysihtml5-dialog-field="target" class="current_target" value="_blank">\n </div>\n\n <a class="button" data-wysihtml5-dialog-action="save">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.save')) == null ? '' : __t) + '\n </a>\n <a class="button" data-wysihtml5-dialog-action="cancel">\n ' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.cancel')) == null ? '' : __t) + '\n </a>\n\n <a data-wysihtml5-command="removeLink">' + ((__t = I18n.t('pageflow.ui.templates.inputs.text_area_input.remove_link')) == null ? '' : __t) + '</a>\n </div>\n</div>\n';
+ return __p;
+ }
/**
* Input view for multi line text with simple formatting options.
+ * See {@link inputWithPlaceholderText} for placeholder related options.
+ * See {@link inputView} for further options.
*
+ * @param {Object} [options]
+ *
* @param {string} [options.size="normal"]
* Pass `"short"` to reduce the text area height.
*
* @param {boolean} [options.disableLinks=false]
* Do not allow links inside the text.
@@ -1803,19 +1968,14 @@
* @param {Backbone.View} [options.fragmentLinkInputView]
* A view to select an id to use in links which only consist
* of a url fragment. Will receive a model with a `linkId`
* attribute.
*
- * @see
- * {@link module:pageflow/ui.inputWithPlaceholderText inputWithPlaceholderText}
- * for placeholder related options
- *
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var TextAreaInputView = Marionette.ItemView.extend({
mixins: [inputView, inputWithPlaceholderText],
template: template$8,
ui: {
input: 'textarea',
@@ -1992,34 +2152,35 @@
this.ui.targetInput.val(this.ui.openInNewTabCheckBox.is(':checked') ? '_blank' : '_self');
}
});
function template$9(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" />\n<div class="validation"></div>\n';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<input type="text" />\n<div class="validation"></div>\n';
+ return __p;
}
-
/**
* Input view for URLs.
+ * See {@link inputView} for further options
*
+ * @param {Object} [options]
+ *
* @param {string[]} options.supportedHosts
* List of allowed url prefixes.
*
* @param {boolean} [options.required=false]
* Display an error if the url is blank.
*
* @param {boolean} [options.permitHttps=false]
* Allow urls with https protocol.
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var UrlInputView = Marionette.Layout.extend(
- /** @lends module:pageflow/ui.UrlInputView# */
+ /** @lends UrlInputView.prototype */
{
mixins: [inputView],
template: template$9,
ui: {
input: 'input',
@@ -2141,11 +2302,10 @@
view.$el.removeClass('invalid');
view.ui.validation.hide();
}
}
});
-
/**
* Input view that verifies that a certain URL is reachable via a
* proxy. To conform with same origin restrictions, this input view
* lets the user enter some url and saves a rewritten url where the
* domain is replaced with some path segment.
@@ -2153,10 +2313,14 @@
* That way, when `/example` is setup to proxy requests to
* `http://example.com`, the user can enter an url of the form
* `http://example.com/some/path` but the string `/example/some/path`
* is persisited to the database.
*
+ * See {@link inputView} for further options
+ *
+ * @param {Object} options
+ *
* @param {string} options.displayPropertyName
* Attribute name to store the url entered by the user.
*
* @param {Object[]} options.proxies
* List of supported proxies.
@@ -2182,17 +2346,15 @@
* base_path: '/example'
* }
* ]
* });
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
var ProxyUrlInputView = UrlInputView.extend(
- /** @lends module:pageflow/ui.ProxyUrlInputView# */
+ /** @lends ProxyUrlInputView.prototype */
{
// @override
validateUrl: function validateUrl(url) {
var view = this;
return $.Deferred(function (deferred) {
@@ -2205,15 +2367,15 @@
status: xhr.status
}));
});
}).promise();
},
- // @override
+ // override
transformPropertyValue: function transformPropertyValue(url) {
return this.rewriteUrl(url);
},
- // @override
+ // override
supportedHosts: function supportedHosts() {
return _$1.pluck(this.options.proxies, 'url');
},
rewriteUrl: function rewriteUrl(url) {
_$1.each(this.options.proxies, function (proxy) {
@@ -2223,23 +2385,24 @@
return url;
}
});
function template$a(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="value"></div>\n<div class="slider"></div>\n';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="value"></div>\n<div class="slider"></div>\n';
+ return __p;
}
-
/**
* A slider for numeric inputs.
+ * See {@link inputView} for options
*
- * @see {@link module:pageflow/ui.inputView inputView} for options
+ * @param {Object} [options]
+ *
* @class
- * @memberof module:pageflow/ui
*/
+
var SliderInputView = Marionette.ItemView.extend({
mixins: [inputView],
className: 'slider_input',
template: template$a,
ui: {
@@ -2275,13 +2438,13 @@
this.ui.widget.slider('option', 'value', value);
}
});
function template$b(data) {
- var __p = '';
- __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<textarea></textarea>\n';
- return __p
+ var __p = '';
+ __p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n\n<textarea></textarea>\n';
+ return __p;
}
var JsonInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$b,
@@ -2344,27 +2507,28 @@
}
}
});
function template$c(data) {
- var __p = '';
- __p += '<input type="checkbox" />\n<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>';
- return __p
+ var __p = '';
+ __p += '<input type="checkbox" />\n<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>';
+ return __p;
}
-
/**
* Input view for boolean values.
+ * See {@link inputView} for further options
*
+ * @param {Object} [options]
+ *
* @param {boolean} [options.displayUncheckedIfDisabled=false]
* Ignore the attribute value if the input is disabled and display
* an unchecked check box.
*
- * @see {@link module:pageflow/ui.inputView inputView} for further options
* @class
- * @memberof module:pageflow/ui
*/
+
var CheckBoxInputView = Marionette.ItemView.extend({
mixins: [inputView],
template: template$c,
className: 'check_box_input',
events: {
@@ -2396,11 +2560,10 @@
} else {
return this.model.get(this.options.propertyName);
}
}
});
-
/**
* A table cell mapping column attribute values to a list of
* translations.
*
* ## Attribute Translations
@@ -2424,27 +2587,28 @@
}));
}
});
function template$d(data) {
- var __t, __p = '';
- __p += '<a class="remove" title="' +
- ((__t = ( I18n.t('pageflow.editor.templates.row.destroy') )) == null ? '' : __t) +
- '"></a>\n';
- return __p
- }
+ var __t,
+ __p = '';
+ __p += '<a class="remove" title="' + ((__t = I18n.t('pageflow.editor.templates.row.destroy')) == null ? '' : __t) + '"></a>\n';
+ return __p;
+ }
/**
* A table cell providing a button which destroys the model that the
* current row refers to.
*
* ## Attribute Translations
*
* The following attribute translation is used:
*
* - `.cell_title` - Used as title attribute.
*
+ * @param {Object} [options]
+ *
* @param {function} [options.toggleDeleteButton]
* A function with boolean return value to be called on
* this.getModel(). Delete button will be visible only if the
* function returns a truthy value.
*
@@ -2452,10 +2616,11 @@
* Invert the return value of `toggleDeleteButton`?
*
* @since 12.0
*/
+
var DeleteRowTableCellView = TableCellView.extend({
className: 'delete_row_table_cell',
template: template$d,
ui: {
removeButton: '.remove'
@@ -2486,11 +2651,10 @@
},
destroy: function destroy() {
this.getModel().destroy();
}
});
-
/**
* A table cell representing whether the column attribute is present
* on the row model.
*
* ## Attribute Translations
@@ -2514,21 +2678,22 @@
value: this.attributeValue()
}) : this.attributeTranslation('cell_title.blank'));
this.$el.toggleClass('is_present', isPresent);
}
});
-
/**
* A table cell mapping column attribute values to icons.
*
* ## Attribute Translations
*
* The following attribute translations are used:
*
* - `.cell_title.<attribute_value>` - Used as title attribute.
* - `.cell_title.blank` - Used as title attribute if attribute is blank.
*
+ * @param {Object} [options]
+ *
* @param {string[]} [options.icons]
* An array of all possible attribute values to be mapped to HTML
* classes of the same name. A global mapping from those classes to
* icon mixins is provided in
* pageflow/ui/table_cells/icon_table_cell.scss.
@@ -2549,16 +2714,17 @@
},
removeExistingIcons: function removeExistingIcons() {
this.$el.removeClass(this.options.icons.join(' '));
}
});
-
/**
* A table cell using the row model's value of the column attribute as
* text. If attribute value is empty, use most specific default
* available.
*
+ * @param {Object} [options]
+ *
* @param {function|string} [options.column.default]
* A function returning a default value for display if attribute
* value is empty.
*
* @param {string} [options.column.contentBinding]
@@ -2594,11 +2760,10 @@
} else {
return I18n$1.t('pageflow.ui.text_table_cell_view.empty');
}
}
});
-
var subviewContainer = {
subview: function subview(view) {
this.subviews = this.subviews || new ChildViewContainer();
this.subviews.add(view.render());
return view;
@@ -2611,11 +2776,10 @@
this.subviews.call('close');
}
}
};
Cocktail.mixin(Marionette.View, subviewContainer);
-
var tooltipContainer = {
events: {
'mouseover [data-tooltip]': function mouseoverDataTooltip(event) {
if (!this.tooltip.visible) {
var target = $(event.target);
@@ -2683,11 +2847,10 @@
* Subclasses that represent failures that are can not be retried should
* override `catRetry` with false.
* Retryable failures should implement `retryAction`.
*
* @class
- * @memberof module:pageflow/editor
*/
var Failure = BaseObject.extend({
canRetry: true,
type: 'Failure',
@@ -2704,29 +2867,13 @@
},
key: function key() {
return this.model.cid + '-' + this.type;
}
});
- /**
- * SavingFailure represents a unsuccessful attempt to save
- * a model on the server.
- *
- * @class
- * @memberof module:pageflow/editor
- */
-
var SavingFailure = Failure.extend({
type: 'SavingFailure'
});
- /**
- * OrderingFailure represent a unsuccessful attempt to save
- * the ordering of a orderedCollection.
- *
- * @class
- * @memberof module:pageflow/editor
- */
-
var OrderingFailure = Failure.extend({
type: 'OrderingFailure',
initialize: function initialize(model, collection) {
Failure.prototype.initialize.call(this, model);
this.collection = collection;
@@ -2746,26 +2893,24 @@
*
* It's possible to add failures to the UI by adding instances of subclasses of Failure:
*
* editor.failures.add(new OrderingFailure(model, collection));
*
- * @alias pageflow.Failures
- * @memberof module:pageflow/editor
+ * @alias Failures
*/
var FailuresAPI = BaseObject.extend(
- /** @lends module:pageflow/editor.pageflow.Failures */
+ /** @lends Failures.prototype */
{
initialize: function initialize() {
this.failures = {};
this.length = 0;
},
/**
* Listen to the `error` and `sync` events of a collection and
- * create {@link module:pageflow/editor.SavingFailure
- * SavingFailure} objects.
+ * create failure objects.
*/
watch: function watch(collection) {
this.listenTo(collection, 'sync', this.remove);
this.listenTo(collection, 'error', function (model) {
if (!model.isNew()) {
@@ -2914,12 +3059,11 @@
args.unshift(this._fileTypes);
return _$1[method].apply(_$1, args);
};
});
- /*global pageflow*/
- var state = pageflow;
+ var state = window.pageflow || {};
function template$e(data) {
var __p = '';
__p += '';
return __p
@@ -3029,21 +3173,22 @@
/**
* Base class for views used as `valueView` for file type meta data
* attributes.
*
+ * @param {Object} [options]
+ *
* @param {string} [options.name]
* Name of the meta data item used in translation keys.
*
* @param {string} [options.settingsDialogTabLink]
* Dispaly a link to open the specified tab of the file settings
* dialog.
*
* @since 12.0
*
* @class
- * @memberof module:pageflow/editor
*/
var FileMetaDataItemValueView = Marionette.ItemView.extend({
template: template$g,
ui: {
@@ -3075,22 +3220,10 @@
toggleEditLink: function toggleEditLink() {
this.ui.editLink.toggle(!!this.options.settingsDialogTabLink && !this.model.isNew());
}
});
- /**
- * Renders the value of the attribute given in `options.name`.
- *
- * @see {@link module:pageflow/editor.FileMetaDataItemValueView
- * FileMetaDataItemValueView} for further options.
- *
- * @since 12.0
- *
- * @class
- * @memberof module:pageflow/editor
- */
-
var TextFileMetaDataItemValueView = FileMetaDataItemValueView.extend({
getText: function getText() {
var model;
if (this.options.fromConfiguration) {
@@ -3247,16 +3380,20 @@
this.importers[name] = config;
config.key = name;
},
setup: function setup(serverSideConfigs) {
this._setup = true;
- var importers = this.importers;
+ var registeredImporters = this.importers;
+ var importers = {};
serverSideConfigs.forEach(function (importer) {
- importers[importer.importerName]['authenticationRequired'] = importer.authenticationRequired;
- importers[importer.importerName]['authenticationProvider'] = importer.authenticationProvider;
- importers[importer.importerName]['logoSource'] = importer.logoSource;
+ var regImporter = registeredImporters[importer.importerName];
+ regImporter['authenticationRequired'] = importer.authenticationRequired;
+ regImporter['authenticationProvider'] = importer.authenticationProvider;
+ regImporter['logoSource'] = importer.logoSource;
+ importers[importer.importerName] = regImporter;
});
+ this.importers = importers;
},
find: function find(name) {
if (!this.importers[name]) {
throw 'Could not find file importer with name "' + name + '"';
}
@@ -3367,10 +3504,66 @@
args.unshift(this.pageTypes);
return _$1[method].apply(_$1, args);
};
});
+ // different model types. Backbone.Collection tries to merge records
+ // if they have the same id.
+
+ var MultiCollection = function MultiCollection() {
+ this.records = {};
+ this.length = 0;
+ };
+
+ _$1.extend(MultiCollection.prototype, {
+ add: function add(record) {
+ if (!this.records[record.cid]) {
+ this.records[record.cid] = record;
+ this.length = _$1.keys(this.records).length;
+ this.trigger('add', record);
+ }
+ },
+ remove: function remove(record) {
+ if (this.records[record.cid]) {
+ delete this.records[record.cid];
+ this.length = _$1.keys(this.records).length;
+ this.trigger('remove', record);
+ }
+ },
+ isEmpty: function isEmpty() {
+ return this.length === 0;
+ }
+ });
+
+ _$1.extend(MultiCollection.prototype, Backbone.Events);
+
+ MultiCollection.extend = Backbone.Collection.extend;
+
+ /**
+ * Watch Backbone collections to track which models are currently
+ * being saved. Used to update the notifications view displaying
+ * saving status/failutes.
+ */
+
+ var SavingRecordsCollection = MultiCollection.extend({
+ /**
+ * Listen to events of models in collection to track when they are
+ * being saved.
+ *
+ * @param {Backbone.Collection} collection - Collection to watch.
+ */
+ watch: function watch(collection) {
+ var that = this;
+ this.listenTo(collection, 'request', function (model, xhr) {
+ that.add(model);
+ xhr.always(function () {
+ that.remove(model);
+ });
+ });
+ }
+ });
+
var WidgetType = BaseObject.extend({
initialize: function initialize(serverSideConfig, clientSideConfig) {
this.name = serverSideConfig.name;
this.translationKey = serverSideConfig.translationKey;
this.configurationEditorView = clientSideConfig.configurationEditorView;
@@ -3431,73 +3624,105 @@
isOptional: function isOptional(role) {
return !!this._optionalRoles[role];
}
});
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
+
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
/**
* Interface for engines providing editor extensions.
* @alias editor
- * @memberof module:pageflow/editor
*/
var EditorApi = BaseObject.extend(
- /** @lends module:pageflow/editor.editor */
+ /** @lends editor */
{
initialize: function initialize(options) {
this.router = options && options.router;
this.sideBarRoutings = [];
this.mainMenuItems = [];
this.initializers = [];
this.fileSelectionHandlers = {};
/**
* Failures API
*
- * @returns {pageflow.Failures}
- *
- * @alias failures
- * @memberof module:pageflow/editor.editor
+ * @returns {Failures}
+ * @memberof editor
*/
this.failures = new FailuresAPI();
/**
+ * Tracking records that are currently being saved.
+ *
+ * @returns {SavingRecordsCollection}
+ * @memberof editor
+ * @since 15.1
+ */
+
+ this.savingRecords = new SavingRecordsCollection();
+ /**
* Set up editor integration for page types.
- * @alias pageTypes
- * @memberof module:pageflow/editor.editor
+ * @memberof editor
*/
this.pageTypes = new PageTypes();
/**
* Add tabs to the configuration editor of all pages.
- * @alias commonPageConfigurationTabs
- * @memberof module:pageflow/editor.editor
+ * @memberof editor
*/
this.commonPageConfigurationTabs = new CommonPageConfigurationTabs();
/**
* Setup editor integration for widget types.
- * @alias widgetType
- * @memberof module:pageflow/editor.editor
+ * @memberof editor
*/
this.widgetTypes = new WidgetTypes();
/**
- * @alias fileTypes
- * @memberof module:pageflow/editor.editor
* Set up editor integration for file types
+ * @memberof editor
*/
this.fileTypes = new FileTypes();
/**
* List of available file import plugins
- * @alias fileImporters
- *
+ * @memberof editor
*/
this.fileImporters = new FileImporters();
},
/**
+ * Configure editor for entry type.
+ *
+ * @param {string} name
+ * Must match name of entry type registered in Ruby configuration.
+ * @param {Object} options
+ * @param {function} options.EntryModel
+ * Backbone model extending {Entry} to store entry state.
+ * @param {function} options.EntryPreviewView
+ * Backbone view that will render the live preview of the entry.
+ * @param {function} options.EntryOutlineView
+ * Backbone view that will be rendered in the side bar.
+ */
+ registerEntryType: function registerEntryType(name, options) {
+ this.entryType = _objectSpread({
+ name: name
+ }, options);
+ },
+ createEntryModel: function createEntryModel(seed, options) {
+ var entry = new this.entryType.entryModel(seed.entry, options);
+
+ if (entry.setupFromEntryTypeSeed) {
+ entry.setupFromEntryTypeSeed(seed.entry_type, state);
+ }
+
+ return entry;
+ },
+
+ /**
* Display Backbone/Marionette View inside the main panel
* of the editor.
*/
showViewInMainPanel: function showViewInMainPanel(view) {
app.mainRegion.show(view);
@@ -3596,11 +3821,11 @@
/**
* File selection handlers let editor extensions use the files view
* to select files for usage in their custom models.
*
- * See {@link module:pageflow/editor.editor.selectFile
+ * See {@link #editorselectfile
* selectFile} method for details how to trigger file selection.
*
* Example:
*
* function MyFileSelectionHandler(options) { this.call =
@@ -3627,11 +3852,11 @@
* the collection name a file type and a the name of a file type
* filter.
*
* @param {string} handlerName
* The name of a handler registered via {@link
- * module:pageflow/editor.editor.registerFileSelectionHandler}.
+ * #editorregisterfileselectionhandler registerFileSelectionHandler}.
*
* @param {Object} payload
* Options passed to the file selection handler.
*
* @example
@@ -3663,34 +3888,33 @@
* Supported options:
* - isAllowed: function which given a page returns true or false depending on
* whether the page is a valid selection
*/
selectPage: function selectPage(options) {
- return this.pageSelectionView.selectPage(options);
+ return this.pageSelectionView.selectPage(_objectSpread({}, options, {
+ entry: state.entry
+ }));
},
createFileSelectionHandler: function createFileSelectionHandler(handlerName, encodedPayload) {
if (!this.fileSelectionHandlers[handlerName]) {
throw 'Unknown FileSelectionHandler ' + handlerName;
}
var payloadJson = JSON.parse(decodeURIComponent(encodedPayload));
- return new this.fileSelectionHandlers[handlerName](payloadJson);
+ return new this.fileSelectionHandlers[handlerName](_objectSpread({}, payloadJson, {
+ entry: state.entry
+ }));
},
createPageConfigurationEditorView: function createPageConfigurationEditorView(page, options) {
var view = this.pageTypes.findByPage(page).createConfigurationEditorView(_$1.extend(options, {
model: page.configuration
}));
this.commonPageConfigurationTabs.apply(view);
return view;
}
});
- /**
- * The Pageflow editor.
- * @module pageflow/editor
- */
-
var editor = new EditorApi();
var startEditor = function startEditor(options) {
$(function () {
$.when($.getJSON('/editor/entries/' + options.entryId + '/seed'), pageflow.browser.detectFeatures()).done(function (result) {
app.start(result[0]);
@@ -3698,10 +3922,83 @@
alert('Error while starting editor.');
});
});
};
+ /**
+ * Mixins for Backbone models and collections that use entry type
+ * specific editor controllers registered via the `editor_app` entry
+ * type option.
+ */
+
+ var entryTypeEditorControllerUrls = {
+ /**
+ * Mixins for Backbone collections that defines `url` method.
+ *
+ * @param {Object} options
+ * @param {String} options.resources - Path suffix of the controller route
+ *
+ * @example
+ *
+ * import {editor, entryTypeEditorControllerUrls} from 'pageflow/editor';
+ *
+ * editor.registerEntryType('test', {
+ // ...
+ });
+ *
+ * export const ItemsCollection = Backbone.Collection.extend({
+ * mixins: [entryTypeEditorControllerUrls.forCollection({resources: 'items'})
+ * });
+ *
+ * new ItemsCollection().url() // => '/editor/entries/10/test/items'
+ */
+ forCollection: function forCollection(_ref) {
+ var resources = _ref.resources;
+ return {
+ url: function url() {
+ return entryTypeEditorControllerUrl(resources);
+ },
+ urlSuffix: function urlSuffix() {
+ return "/".concat(resources);
+ }
+ };
+ },
+
+ /**
+ * Mixins for Backbone models that defines `urlRoot` method.
+ *
+ * @param {Object} options
+ * @param {String} options.resources - Path suffix of the controller route
+ *
+ * @example
+ *
+ * import {editor, entryTypeEditorControllerUrls} from 'pageflow/editor';
+ *
+ * editor.registerEntryType('test', {
+ // ...
+ });
+ *
+ * export const Item = Backbone.Model.extend({
+ * mixins: [entryTypeEditorControllerUrls.forModel({resources: 'items'})
+ * });
+ *
+ * new Item({id: 20}).url() // => '/editor/entries/10/test/items/20'
+ */
+ forModel: function forModel(_ref2) {
+ var resources = _ref2.resources;
+ return {
+ urlRoot: function urlRoot() {
+ return this.isNew() ? this.collection.url() : entryTypeEditorControllerUrl(resources);
+ }
+ };
+ }
+ };
+
+ function entryTypeEditorControllerUrl(resources) {
+ return [state.entry.url(), editor.entryType.name, resources].join('/');
+ }
+
var formDataUtils = {
fromModel: function fromModel(model) {
var object = {};
object[model.modelName] = model.toJSON();
return this.fromObject(object);
@@ -3805,11 +4102,11 @@
clear: function clear() {
this.parent.remove(this.models);
this.reset();
},
url: function url() {
- return this.parentModel.url() + _$1.result(this.parent, 'url');
+ return this.parentModel.url() + (_$1.result(this.parent, 'urlSuffix') || _$1.result(this.parent, 'url'));
},
dispose: function dispose() {
this.stopListening();
this.reset();
}
@@ -3916,11 +4213,11 @@
});
var EditLock = Backbone.Model.extend({
paramRoot: 'edit_lock',
url: function url() {
- return state.entry.url() + '/edit_lock?timestamp=' + new Date().getTime();
+ return '/entries/' + state.entry.get('id') + '/edit_lock?timestamp=' + new Date().getTime();
},
toJSON: function toJSON() {
return {
id: this.id,
force: this.get('force')
@@ -4114,14 +4411,26 @@
});
app.on('mixin:configuration', function (mixin) {
Cocktail.mixin(Configuration, mixin);
});
+ /**
+ * Remove model from collection only after the `DELETE` request has
+ * succeeded. Still allow tracking that the model is being destroyed
+ * by triggering a `destroying` event and adding a `isDestroying`
+ * method.
+ */
+
var delayedDestroying = {
initialize: function initialize() {
this._destroying = false;
},
+
+ /**
+ * Trigger `destroying` event and send `DELETE` request. Only remove
+ * model from collection once the request is done.
+ */
destroyWithDelay: function destroyWithDelay() {
var model = this;
this._destroying = true;
this.trigger('destroying', this);
return Backbone.Model.prototype.destroy.call(this, {
@@ -4132,15 +4441,23 @@
error: function error() {
model._destroying = false;
}
});
},
+
+ /**
+ * Get whether the model is currently being destroyed.
+ */
isDestroying: function isDestroying() {
return this._destroying;
}
};
+ /**
+ * Mixin for Backbone models that shall be watched by {@link
+ * modelLifecycleTrackingView} mixin.
+ */
var failureTracking = {
initialize: function initialize() {
this._saveFailed = false;
this.listenTo(this, 'sync', function () {
this._saveFailed = false;
@@ -4733,13 +5050,27 @@
return '';
}
});
- var EntryConfiguration = Configuration.extend({
+ var EntryMetadataConfiguration = Configuration.extend({
+ modelName: 'entry_metadata_configuration',
+ i18nKey: 'pageflow/entry_metadata_configuration',
+ defaults: {}
+ });
+
+ var EntryMetadata = Configuration.extend({
modelName: 'entry',
- i18nKey: 'pageflow/entry'
+ i18nKey: 'pageflow/entry',
+ defaults: {},
+ initialize: function initialize(attributes, options) {
+ this.configuration = new EntryMetadataConfiguration(_$1.clone(attributes.configuration) || {});
+ this.listenTo(this.configuration, 'change', function () {
+ this.trigger('change');
+ this.parent.save();
+ });
+ }
});
var StorylineConfiguration = Configuration.extend({
modelName: 'storyline',
i18nKey: 'pageflow/storyline',
@@ -4914,20 +5245,20 @@
isPositionable: function isPositionable() {
return this.isReady();
}
});
- var EntryConfigurationFileSelectionHandler = function EntryConfigurationFileSelectionHandler(options) {
+ var EntryMetadataFileSelectionHandler = function EntryMetadataFileSelectionHandler(options) {
this.call = function (file) {
- state.entry.configuration.setReference(options.attributeName, file);
+ state.entry.metadata.setReference(options.attributeName, file);
};
this.getReferer = function () {
return '/meta_data/' + (options.returnToTab || 'general');
};
};
- editor.registerFileSelectionHandler('entryConfiguration', EntryConfigurationFileSelectionHandler);
+ editor.registerFileSelectionHandler('entryMetadata', EntryMetadataFileSelectionHandler);
var EntryPublication = Backbone.Model.extend({
paramRoot: 'entry_publication',
quota: function quota() {
return new Backbone.Model(this.get('quota') || {});
@@ -4970,11 +5301,24 @@
this.chapter.set(response.chapter);
this.page.set(response.page);
}
});
- var EntryData = BaseObject.extend({
+ // https://github.com/jashkenas/backbone/issues/2601
+
+ function BaseObject$1(options) {
+ this.initialize.apply(this, arguments);
+ }
+
+ _$1.extend(BaseObject$1.prototype, Backbone.Events, {
+ initialize: function initialize(options) {}
+ }); // The self-propagating extend function that Backbone classes use.
+
+
+ BaseObject$1.extend = Backbone.Model.extend;
+
+ var EntryData = BaseObject$1.extend({
getThemingOption: function getThemingOption(name) {
throw 'Not implemented';
},
getFile: function getFile(collectionName, id) {
throw 'Not implemented';
@@ -5567,10 +5911,80 @@
return '/page_links/' + pageLink.id;
};
};
editor.registerFileSelectionHandler('pageLink', PageLinkFileSelectionHandler);
+ /**
+ * Mixins for models with a nested configuration model.
+ *
+ * Triggers events on the parent model of the form
+ * `change:configuration` and `change:configuration:<attribute>`, when
+ * the configuration changes.
+ *
+ * @param {Object} [options]
+ * @param {Function} [options.configurationModel] -
+ * Backbone model to use for nested configuration model.
+ * @param {Boolean} [options.autoSave] -
+ * Save model when configuration changes.
+ * @param {Boolean|Array<String>} [options.includeAttributesInJSON] -
+ * Include all or specific attributes of the parent model in the
+ * data returned by `toJSON` besides the `configuration` property.
+ * @returns {Object} - Mixin to be included in model.
+ *
+ * @example
+ *
+ * import {configurationContainer} from 'pageflow/editor';
+ *
+ * const Section = Backbone.Model.extend({
+ * mixins: [configurationContainer({autoSave: true})]
+ * });
+ *
+ * const section = new Section({configuration: {some: 'value'}});
+ * section.configuration.get('some') // => 'value';
+ */
+
+ function configurationContainer() {
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
+ configurationModel = _ref.configurationModel,
+ autoSave = _ref.autoSave,
+ includeAttributesInJSON = _ref.includeAttributesInJSON;
+
+ configurationModel = configurationModel || Configuration.extend({
+ defaults: {}
+ });
+ return {
+ initialize: function initialize() {
+ this.configuration = new configurationModel(this.get('configuration'));
+ this.configuration.parent = this;
+ this.listenTo(this.configuration, 'change', function () {
+ if (!this.isNew() && autoSave) {
+ this.save();
+ }
+
+ this.trigger('change:configuration', this);
+
+ _$1.chain(this.configuration.changed).keys().each(function (name) {
+ this.trigger('change:configuration:' + name, this, this.configuration.get(name));
+ }, this);
+ });
+ },
+ toJSON: function toJSON() {
+ var attributes = {};
+
+ if (includeAttributesInJSON === true) {
+ attributes = _$1.clone(this.attributes);
+ } else if (includeAttributesInJSON) {
+ attributes = _$1.pick(this.attributes, includeAttributesInJSON);
+ }
+
+ return _$1.extend(attributes, {
+ configuration: this.configuration.toJSON()
+ });
+ }
+ };
+ }
+
var persistedPromise = {
persisted: function persisted() {
var model = this;
this._persistedDeferred = this._persistedDeferred || $.Deferred(function (deferred) {
if (model.isNew()) {
@@ -5643,19 +6057,19 @@
}
};
var Entry = Backbone.Model.extend({
paramRoot: 'entry',
- urlRoot: '/entries',
+ urlRoot: '/editor/entries',
modelName: 'entry',
i18nKey: 'pageflow/entry',
collectionName: 'entries',
mixins: [filesCountWatcher, polling, failureTracking],
initialize: function initialize(attributes, options) {
options = options || {};
- this.configuration = new EntryConfiguration(this.get('configuration') || {});
- this.configuration.parent = this;
+ this.metadata = new EntryMetadata(this.get('metadata') || {});
+ this.metadata.parent = this;
this.themes = options.themes || state.themes;
this.files = options.files || state.files;
this.fileTypes = options.fileTypes || editor.fileTypes;
this.storylines = options.storylines || state.storylines;
this.storylines.parentModel = this;
@@ -5673,25 +6087,28 @@
this.pages.sort();
});
this.listenTo(this.chapters, 'sort', function () {
this.pages.sort();
});
- this.listenTo(this.configuration, 'change', function () {
- this.trigger('change:configuration');
+ this.listenTo(this.metadata, 'change', function () {
+ this.trigger('change:metadata');
this.save();
});
- this.listenTo(this.configuration, 'change:locale', function () {
+ this.listenTo(this.metadata, 'change:locale', function () {
this.once('sync', function () {
// No other way of updating page templates used in
// EntryPreviewView at the moment.
location.reload();
});
});
},
getTheme: function getTheme() {
- return this.themes.findByName(this.configuration.get('theme_name'));
+ return this.themes.findByName(this.metadata.get('theme_name'));
},
+ supportsPhoneEmulation: function supportsPhoneEmulation() {
+ return pageflow.features.isEnabled('editor_emulation_mode');
+ },
addStoryline: function addStoryline(attributes) {
var storyline = this.buildStoryline(attributes);
storyline.save();
return storyline;
},
@@ -5769,11 +6186,14 @@
}, options));
delete response[fileType.collectionName];
}, this);
},
toJSON: function toJSON() {
- return this.configuration.toJSON();
+ var metadataJSON = this.metadata.toJSON();
+ var configJSON = this.metadata.configuration.toJSON();
+ metadataJSON.configuration = configJSON;
+ return metadataJSON;
}
});
var AuthenticationProvider = BaseObject.extend({
authenticate: function authenticate(parent, provider) {
@@ -5927,10 +6347,65 @@
comparator: function comparator(chapter) {
return chapter.get('position');
}
});
+ /**
+ * A Backbone collection that is automatically updated to only
+ * contain models with a foreign key matching the id of a parent
+ * model.
+ *
+ * @param {Object} options
+ * @param {Backbone.Model} options.parentModel -
+ * Model whose id is compared to foreign keys.
+ * @param {Backbone.Collection} options.parent -
+ * Collection to filter items with matching foreign key from.
+ * @param {String} options.foreignKeyAttribute -
+ * Attribute to compare to id of parent model.
+ * @param {String} options.parentReferenceAttribute -
+ * Set reference to parent model on models in collection.
+ *
+ * @since 15.1
+ */
+
+ var ForeignKeySubsetCollection = SubsetCollection.extend({
+ mixins: [orderedCollection],
+ constructor: function constructor(options) {
+ var parent = options.parent;
+ var parentModel = options.parentModel;
+ SubsetCollection.prototype.constructor.call(this, {
+ parent: parent,
+ parentModel: parentModel,
+ filter: function filter(item) {
+ return !parentModel.isNew() && item.get(options.foreignKeyAttribute) === parentModel.id;
+ },
+ comparator: function comparator(item) {
+ return item.get('position');
+ }
+ });
+ this.listenTo(this, 'add', function (model) {
+ if (options.parentReferenceAttribute) {
+ model[options.parentReferenceAttribute] = parentModel;
+ }
+
+ model.set(options.foreignKeyAttribute, parentModel.id);
+ });
+ this.listenTo(parentModel, 'destroy', function () {
+ this.clear();
+ });
+
+ if (options.parentReferenceAttribute) {
+ this.each(function (model) {
+ return model[options.parentReferenceAttribute] = parentModel;
+ });
+ this.listenTo(this, 'remove', function (model) {
+ model[options.parentReferenceAttribute] = null;
+ });
+ }
+ }
+ });
+
var PageLinksCollection = Backbone.Collection.extend({
model: PageLink,
initialize: function initialize(models, options) {
this.configuration = options.configuration;
this.page = options.configuration.page;
@@ -6146,54 +6621,10 @@
return model;
}
};
Cocktail.mixin(Backbone.Collection, addAndReturnModel);
- // different model types. Backbone.Collection tries to merge records
- // if they have the same id.
-
- var MultiCollection = function MultiCollection() {
- this.records = {};
- this.length = 0;
- };
-
- _$1.extend(MultiCollection.prototype, {
- add: function add(record) {
- if (!this.records[record.cid]) {
- this.records[record.cid] = record;
- this.length = _$1.keys(this.records).length;
- this.trigger('add', record);
- }
- },
- remove: function remove(record) {
- if (this.records[record.cid]) {
- delete this.records[record.cid];
- this.length = _$1.keys(this.records).length;
- this.trigger('remove', record);
- }
- },
- isEmpty: function isEmpty() {
- return this.length === 0;
- }
- });
-
- _$1.extend(MultiCollection.prototype, Backbone.Events);
-
- MultiCollection.extend = Backbone.Collection.extend;
-
- var SavingRecordsCollection = MultiCollection.extend({
- watch: function watch(collection) {
- var that = this;
- this.listenTo(collection, 'request', function (model, xhr) {
- that.add(model);
- xhr.always(function () {
- that.remove(model);
- });
- });
- }
- });
-
var SidebarRouter = Marionette.AppRouter.extend({
appRoutes: {
'page_links/:id': 'pageLink',
'pages/:id': 'page',
'pages/:id/:tab': 'page',
@@ -6233,10 +6664,11 @@
},
onRender: function onRender() {
this.outlet.show(this.options.view);
},
goBack: function goBack() {
+ this.options.view.onGoBack && this.options.view.onGoBack();
editor.navigate('/', {
trigger: true
});
}
});
@@ -6370,28 +6802,91 @@
return new BackButtonDecoratorView({
view: new ConfirmEncodingView(options)
});
};
- var failureIndicatingView = {
- modelEvents: {
- 'change:failed': 'updateFailIndicator'
- },
- events: {
- 'click .retry': function clickRetry() {
+ /**
+ * Mixin for Marionette Views that sets css class names according to
+ * life cycle events of its model.
+ *
+ * @param {Object} options
+ * @param {Object} options.classNames
+ * @param {String} options.classNames.creating -
+ * Class name to add to root element while model is still being created.
+ * @param {String} options.classNames.destroying -
+ * Class name to add to root element while model is being destroyed.
+ * @param {String} options.classNames.failed -
+ * Class name to add to root element while model is in failed state.
+ * Model needs to include {@link failureTracking} mixin.
+ * @param {String} options.classNames.failureMessage -
+ * Class name of the element that shall be updated with the failure
+ * message. Model needs to include {@link failureTracking} mixin.
+ * @param {String} options.classNames.retryButton -
+ * Class name of the element that shall act as a retry button.
+ */
+
+ function modelLifecycleTrackingView(_ref) {
+ var classNames = _ref.classNames;
+ return {
+ events: _defineProperty({}, "click .".concat(classNames.retryButton), function click() {
editor.failures.retry();
return false;
+ }),
+ initialize: function initialize() {
+ var _this = this;
+
+ if (classNames.creating) {
+ this.listenTo(this.model, 'change:id', function () {
+ this.$el.removeClass(classNames.creating);
+ });
+ }
+
+ if (classNames.destroying) {
+ this.listenTo(this.model, 'destroying', function () {
+ this.$el.addClass(classNames.destroying);
+ });
+ this.listenTo(this.model, 'error', function () {
+ this.$el.removeClass(classNames.destroying);
+ });
+ }
+
+ if (classNames.failed || classNames.failureMessage) {
+ this.listenTo(this.model, 'change:failed', function () {
+ return _this.updateFailIndicator();
+ });
+ }
+ },
+ render: function render() {
+ if (this.model.isNew()) {
+ this.$el.addClass(classNames.creating);
+ }
+
+ if (this.model.isDestroying && this.model.isDestroying()) {
+ this.$el.addClass(classNames.destroying);
+ }
+
+ this.updateFailIndicator();
+ },
+ updateFailIndicator: function updateFailIndicator() {
+ if (classNames.failed) {
+ this.$el.toggleClass(classNames.failed, this.model.isFailed());
+ }
+
+ if (classNames.failureMessage) {
+ this.$el.find(".".concat(classNames.failureMessage)).text(this.model.getFailureMessage());
+ }
}
- },
- onRender: function onRender() {
- this.updateFailIndicator();
- },
- updateFailIndicator: function updateFailIndicator() {
- this.$el.toggleClass('failed', this.model.isFailed());
- this.$el.find('.failure .message').text(this.model.getFailureMessage());
+ };
+ }
+
+ var failureIndicatingView = modelLifecycleTrackingView({
+ classNames: {
+ failed: 'failed',
+ failureMessage: 'failure .message',
+ retryButton: 'retry'
}
- };
+ });
function template$k(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_chapter.outline') )) == null ? '' : __t) +
@@ -6447,449 +6942,36 @@
});
}
});
function template$l(data) {
- var __p = '';
- __p += '<div class="pictogram"></div>\n';
- return __p
- }
-
- var FileThumbnailView = Marionette.ItemView.extend({
- className: 'file_thumbnail',
- template: template$l,
- modelEvents: {
- 'change:state': 'update'
- },
- ui: {
- pictogram: '.pictogram'
- },
- onRender: function onRender() {
- this.update();
- },
- update: function update() {
- if (this.model) {
- var stage = this.model.currentStage();
-
- if (stage) {
- this.setStageClassName(stage.get('name'));
- this.ui.pictogram.toggleClass('action_required', stage.get('action_required'));
- this.ui.pictogram.toggleClass('failed', stage.get('failed'));
- } else {
- this.ui.pictogram.removeClass(this.model.stages.pluck('name').join(' '));
- }
-
- this.ui.pictogram.addClass(this.model.thumbnailPictogram);
- this.$el.css('background-image', this._imageUrl() ? 'url(' + this._imageUrl() + ')' : '');
- this.$el.removeClass('empty').toggleClass('always_picogram', !!this.model.thumbnailPictogram).toggleClass('ready', this.model.isReady());
- } else {
- this.$el.css('background-image', '');
- this.$el.removeClass('ready');
- this.ui.pictogram.addClass('empty');
- }
- },
- setStageClassName: function setStageClassName(name) {
- if (!this.$el.hasClass(name)) {
- this.ui.pictogram.removeClass('empty');
- this.ui.pictogram.removeClass(this.model.stages.pluck('name').join(' '));
- this.ui.pictogram.addClass(name);
- }
- },
- _imageUrl: function _imageUrl() {
- return this.model.get(this.options.imageUrlPropertyName || 'thumbnail_url');
- }
- });
-
- function template$m(data) {
- var __p = '';
- __p += '\n';
- return __p
- }
-
- var StaticThumbnailView = Marionette.ItemView.extend({
- template: template$m,
- className: 'static_thumbnail',
- modelEvents: {
- 'change:configuration': 'update'
- },
- onRender: function onRender() {
- this.update();
- },
- update: function update() {
- this.$el.css('background-image', 'url(' + this._imageUrl() + ')');
- },
- _imageUrl: function _imageUrl() {
- return this.model.thumbnailUrl();
- }
- });
-
- /**
- * Base thumbnail view for models supporting a `thumbnailFile` method.
- *
- * @class
- * @memberof module:pageflow/editor
- */
-
- var ModelThumbnailView = Marionette.View.extend({
- className: 'model_thumbnail',
- modelEvents: {
- 'change:configuration': 'update'
- },
- render: function render() {
- this.update();
- return this;
- },
- update: function update() {
- if (this.model) {
- if (_$1.isFunction(this.model.thumbnailFile)) {
- var file = this.model && this.model.thumbnailFile();
-
- if (this.thumbnailView && this.currentFileThumbnail == file) {
- return;
- }
-
- this.currentFileThumbnail = file;
- this.newThumbnailView = new FileThumbnailView({
- model: file,
- className: 'thumbnail file_thumbnail',
- imageUrlPropertyName: this.options.imageUrlPropertyName
- });
- } else {
- this.newThumbnailView = this.newThumbnailView || new StaticThumbnailView({
- model: this.model
- });
- }
- }
-
- if (this.thumbnailView) {
- this.thumbnailView.close();
- }
-
- if (this.model) {
- this.thumbnailView = this.subview(this.newThumbnailView);
- this.$el.append(this.thumbnailView.el);
- }
- }
- });
-
- var PageThumbnailView = ModelThumbnailView.extend({
- className: 'model_thumbnail page_thumbnail'
- });
-
- function template$n(data) {
var __t, __p = '';
- __p += '<a href="">\n <span class="type_pictogram"></span>\n <span class="page_thumbnail"></span>\n <span class="title"></span>\n <span class="failure_icon" title="' +
- ((__t = ( I18n.t('pageflow.editor.templates.page_item.save_error') )) == null ? '' : __t) +
- '" />\n</a>\n';
- return __p
- }
-
- var PageItemView = Marionette.ItemView.extend({
- tagName: 'li',
- template: template$n,
- ui: {
- title: '.title',
- pictogram: '.type_pictogram',
- pageThumbnail: '.page_thumbnail'
- },
- modelEvents: {
- 'change:title': 'update',
- 'change:active': 'update'
- },
- onRender: function onRender() {
- this.subview(new PageThumbnailView({
- el: this.ui.pageThumbnail,
- model: this.model
- }));
- this.update();
- },
- update: function update() {
- this.$el.attr('data-id', this.model.id);
- this.$el.attr('data-perma-id', this.model.get('perma_id'));
- this.$el.toggleClass('active', this.model.get('active'));
- this.$el.toggleClass('disabled', !!(this.options.isDisabled && this.options.isDisabled(this.model)));
- this.$el.toggleClass('display_in_navigation', !!this.model.configuration.get('display_in_navigation'));
- this.$el.removeClass(editor.pageTypes.pluck('name').join(' ')).addClass(this.model.get('template'));
- this.ui.pictogram.attr('title', this._getPictogramTitle());
- this.ui.title.text(this.model.title() || I18n$1.t('pageflow.editor.views.page_item_view.unnamed'));
- },
- _getPictogramTitle: function _getPictogramTitle() {
- var result = I18n$1.t(this.model.pageType().translationKey());
- result += ' Seite';
-
- if (this.options.displayInNavigationHint && !this.model.configuration.get('display_in_navigation')) {
- result += ' (nicht in Navigationsleiste)';
- }
-
- return result;
- }
- });
-
- var loadable = {
- modelEvents: {
- 'change:id': function changeId() {
- this.$el.removeClass('creating');
- },
- destroying: function destroying() {
- this.$el.addClass('destroying');
- },
- error: function error() {
- this.$el.removeClass('destroying');
- }
- },
- render: function render() {
- if (this.model.isNew()) {
- this.$el.addClass('creating');
- }
-
- if (this.model.isDestroying && this.model.isDestroying()) {
- this.$el.addClass('destroying');
- }
- }
- };
-
- var NavigatablePageItemView = PageItemView.extend({
- mixins: [loadable, failureIndicatingView],
- className: 'draggable',
- events: {
- 'click': function click() {
- if (!this.model.isNew() && !this.model.isDestroying()) {
- editor.navigate('/pages/' + this.model.get('id'), {
- trigger: true
- });
- }
-
- return false;
- }
- }
- });
-
- function template$o(data) {
- var __t, __p = '';
- __p += '<a class="edit_chapter" href="">\n <span class="pictogram"></span>\n <span class="number"></span>\n <span class="title"></span>\n <span class="failure_icon" title=' +
- ((__t = ( I18n.t('pageflow.editor.templates.chapter_item.save_error') )) == null ? '' : __t) +
- ' />\n</a>\n\n<ul class="pages outline"></ul>\n\n<a href="" class="add_page">' +
- ((__t = ( I18n.t('pageflow.editor.templates.chapter_item.new_page') )) == null ? '' : __t) +
- '</a>\n';
- return __p
- }
-
- var ChapterItemView = Marionette.ItemView.extend({
- tagName: 'li',
- template: template$o,
- ui: {
- title: '> a > .title',
- number: '> a > .number',
- pages: 'ul.pages'
- },
- modelEvents: {
- change: 'update'
- },
- onRender: function onRender() {
- var collectionView = this.options.sortable ? SortableCollectionView : CollectionView;
- this.subview(new collectionView({
- el: this.ui.pages,
- collection: this.model.pages,
- itemViewConstructor: this.options.pageItemView || NavigatablePageItemView,
- itemViewOptions: this.options.pageItemViewOptions,
- connectWith: 'ul.pages'
- }));
- this.update();
- },
- update: function update() {
- this.ui.title.text(this.model.get('title') || I18n$1.t('pageflow.editor.views.chapter_item_view.unnamed'));
- this.ui.number.text(I18n$1.t('pageflow.editor.views.chapter_item_view.chapter') + ' ' + (this.model.get('position') + 1));
- }
- });
-
- var NavigatableChapterItemView = ChapterItemView.extend({
- mixins: [loadable, failureIndicatingView],
- events: {
- 'click a.add_page': function clickAAdd_page() {
- this.model.addPage();
- },
- 'click a.edit_chapter': function clickAEdit_chapter() {
- if (!this.model.isNew() && !this.model.isDestroying()) {
- editor.navigate('/chapters/' + this.model.get('id'), {
- trigger: true
- });
- }
-
- return false;
- }
- }
- });
-
- function template$p(data) {
- var __t, __p = '';
- __p += '<h2>' +
- ((__t = ( I18n.t('pageflow.editor.templates.storyline_outline.header') )) == null ? '' : __t) +
- '</h2>\n<ul class="storyline_outline_chapters chapters"></ul>\n\n<a class="add_chapter" href="">' +
- ((__t = ( I18n.t('pageflow.editor.templates.storyline_outline.new_chapter') )) == null ? '' : __t) +
- '</a>\n';
- return __p
- }
-
- var StorylineOutlineView = Marionette.Layout.extend({
- template: template$p,
- className: 'storyline_outline',
- ui: {
- chapters: 'ul.storyline_outline_chapters'
- },
- events: {
- 'click a.add_chapter': function clickAAdd_chapter() {
- this.model.scaffoldChapter();
- }
- },
- onRender: function onRender() {
- this.ui.chapters.toggleClass('outline navigatable', !!this.options.navigatable);
- var collectionView = this.options.sortable ? SortableCollectionView : CollectionView;
- new collectionView({
- el: this.ui.chapters,
- collection: this.model.chapters,
- itemViewConstructor: this.options.navigatable ? NavigatableChapterItemView : ChapterItemView,
- itemViewOptions: {
- sortable: this.options.sortable,
- pageItemView: this.options.navigatable ? NavigatablePageItemView : PageItemView,
- pageItemViewOptions: _$1.extend({
- displayInNavigationHint: this.options.displayInNavigationHint
- }, this.options.pageItemViewOptions || {})
- }
- }).render();
- }
- });
-
- function template$q(data) {
- var __t, __p = '';
- __p += '<div class="storyline_picker_storylines">\n <div class="storyline_picker_select_region"></div>\n <a href="" class="add_storyline" title="' +
- ((__t = ( I18n.t('pageflow.editor.templates.storyline_picker.add') )) == null ? '' : __t) +
- '"></a>\n <a href="" class="edit_storyline" title="' +
- ((__t = ( I18n.t('pageflow.editor.templates.storyline_picker.edit') )) == null ? '' : __t) +
- '"></a>\n</div>\n\n<div class="storyline_picker_main_region"></div>\n';
- return __p
- }
-
- var StorylinePickerView = Marionette.Layout.extend({
- template: template$q,
- className: 'storyline_picker',
- regions: {
- selectRegion: '.storyline_picker_select_region',
- mainRegion: '.storyline_picker_main_region'
- },
- ui: {
- storylines: '.storyline_picker_storylines'
- },
- events: {
- 'click .add_storyline': function clickAdd_storyline() {
- var storyline = state.entry.scaffoldStoryline({
- depth: 'page'
- }).storyline;
- this.listenToOnce(storyline, 'sync', function () {
- this.updateSelect();
- this.model.set('storyline_id', storyline.id);
- });
- return false;
- },
- 'click .edit_storyline': function clickEdit_storyline() {
- editor.navigate('storylines/' + this.model.get('storyline_id'), {
- trigger: true
- });
- return false;
- }
- },
- initialize: function initialize() {
- this.model = new Backbone.Model({
- storyline_id: this.defaultStorylineId()
- });
- this.listenTo(state.storylines, 'add sort remove', this.updateSelect);
- this.listenTo(this.model, 'change', this.load);
- },
- onRender: function onRender() {
- this.$el.toggleClass('editable', !!this.options.editable);
- this.ui.storylines.toggle(!!pageflow.features.isEnabled('storylines'));
- this.updateSelect();
- this.load();
- },
- updateSelect: function updateSelect() {
- this.selectRegion.show(new SelectInputView({
- model: this.model,
- label: I18n$1.t('pageflow.editor.views.storylines_picker_view.label'),
- propertyName: 'storyline_id',
- values: state.storylines.pluck('id'),
- texts: state.storylines.map(function (storyline) {
- return this.indentation(storyline) + storyline.displayTitle();
- }, this),
- groups: state.storylines.reduce(function (result, storyline) {
- if (storyline.isMain() || storyline.parentPage()) {
- result.push(_$1.last(result));
- } else {
- result.push(I18n$1.t('pageflow.editor.views.storylines_picker_view.without_parent_page'));
- }
-
- return result;
- }, [])
- }));
- },
- load: function load() {
- var storyline = state.storylines.get(this.model.get('storyline_id'));
- this.saveRememberedStorylineId(storyline.id);
- this.mainRegion.show(new StorylineOutlineView({
- model: storyline,
- navigatable: this.options.navigatable,
- sortable: this.options.editable,
- chapterItemView: this.options.chapterItemView,
- pageItemView: this.options.pageItemView,
- pageItemViewOptions: this.options.pageItemViewOptions,
- displayInNavigationHint: this.options.displayInNavigationHint
- }));
- },
- defaultStorylineId: function defaultStorylineId() {
- var storyline = state.storylines.get(this.options.storylineId) || state.storylines.get(this.rememberedStorylineId()) || state.storylines.first();
- return storyline.id;
- },
- rememberedStorylineId: function rememberedStorylineId() {
- if (this.options.rememberLastSelection) {
- return StorylinePickerView._rememberedStorylineId;
- }
- },
- saveRememberedStorylineId: function saveRememberedStorylineId(id) {
- if (this.options.rememberLastSelection) {
- StorylinePickerView._rememberedStorylineId = id;
- }
- },
- indentation: function indentation(storyline) {
- return _$1(storyline.get('level') || 0).times(function () {
- return "\xA0\xA0\xA0";
- }).join('');
- }
- });
-
- function template$r(data) {
- var __t, __p = '';
__p += '<a class="close" href="#">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_entry.close') )) == null ? '' : __t) +
'</a>\n<a class="publish" href="#" data-tooltip-align="bottom right">\n ' +
((__t = ( I18n.t('pageflow.editor.templates.edit_entry.publish') )) == null ? '' : __t) +
'\n</a>\n\n<ul class="menu">\n <li>\n <a class="edit_entry_meta_data" href="#" data-path="/meta_data">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_entry.metadata') )) == null ? '' : __t) +
'</a>\n <span class="failure_icon" title="' +
((__t = ( I18n.t('pageflow.editor.templates.edit_entry.save_error') )) == null ? '' : __t) +
'" />\n </li>\n <li>\n <a class="manage_files" href="#" data-path="/files">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_entry.manage_files') )) == null ? '' : __t) +
- '</a>\n </li>\n</ul>\n\n<div class="edit_entry_storylines storyline_picker"></div>\n';
+ '</a>\n </li>\n</ul>\n\n<div class="edit_entry_outline_region"></div>\n';
return __p
}
- var EditEntryView = Marionette.ItemView.extend({
- template: template$r,
+ var EditEntryView = Marionette.Layout.extend({
+ template: template$l,
mixins: [failureIndicatingView, tooltipContainer],
ui: {
publishButton: 'a.publish',
publicationStateButton: 'a.publication_state',
- menu: '.menu',
- storylines: '.edit_entry_storylines'
+ menu: '.menu'
},
+ regions: {
+ outlineRegion: '.edit_entry_outline_region'
+ },
events: {
'click a.close': function clickAClose() {
$.when(state.editLock.release()).then(function () {
window.location = '/admin/entries/' + state.entry.id;
});
@@ -6913,21 +6995,21 @@
onRender: function onRender() {
this._addMenuItems();
this._updatePublishButton();
- this.subview(new StorylinePickerView({
- el: this.ui.storylines,
+ this.outlineRegion.show(new editor.entryType.outlineView({
+ entry: state.entry,
navigatable: true,
editable: true,
displayInNavigationHint: true,
rememberLastSelection: true,
storylineId: this.options.storylineId
}));
},
_updatePublishButton: function _updatePublishButton() {
- var disabled = !state.entry.get('publishable');
+ var disabled = !this.model.get('publishable');
this.ui.publishButton.toggleClass('disabled', disabled);
if (disabled) {
this.ui.publishButton.attr('data-tooltip', 'pageflow.editor.views.edit_entry_view.cannot_publish');
} else {
@@ -6954,20 +7036,20 @@
view.ui.menu.append(item);
});
}
});
- function template$s(data) {
+ function template$m(data) {
var __t, __p = '';
__p += '<div class="widget_type">\n</div>\n<a class="settings" title="' +
((__t = ( I18n.t('pageflow.editor.templates.widget_item.settings') )) == null ? '' : __t) +
'"></a>\n';
return __p
}
var WidgetItemView = Marionette.Layout.extend({
- template: template$s,
+ template: template$m,
tagName: 'li',
className: 'widget_item',
regions: {
widgetTypeContainer: '.widget_type'
},
@@ -7003,18 +7085,18 @@
update: function update() {
this.$el.toggleClass('has_settings', this.model.hasConfiguration());
}
});
- function template$t(data) {
+ function template$n(data) {
var __p = '';
__p += '<ol class="widgets">\n</ol>\n';
return __p
}
var EditWidgetsView = Marionette.Layout.extend({
- template: template$t,
+ template: template$n,
ui: {
widgets: '.widgets'
},
onRender: function onRender() {
this.subview(new CollectionView({
@@ -7026,18 +7108,18 @@
}
}).render());
}
});
- function template$u(data) {
+ function template$o(data) {
var __p = '';
__p += '<div class="image"></div>\n<div class="label"></div>\n';
return __p
}
var BackgroundPositioningPreviewView = Marionette.ItemView.extend({
- template: template$u,
+ template: template$o,
className: 'preview',
modelEvents: {
change: 'update'
},
ui: {
@@ -7064,18 +7146,18 @@
var file = this.model.getReference(this.options.propertyName, this.options.filesCollection);
return file ? 'url("' + file.getBackgroundPositioningImageUrl() + '")' : 'none';
}
});
- function template$v(data) {
+ function template$p(data) {
var __p = '';
__p += '<div class="container">\n <div class="slider horizontal">\n </div>\n <div class="slider vertical">\n </div>\n <div class="percent horizontal">\n <input type="number" min="0" max="100">\n %\n </div>\n <div class="percent vertical">\n <input type="number" min="0" max="100">\n %\n </div>\n</div>\n';
return __p
}
var BackgroundPositioningSlidersView = Marionette.ItemView.extend({
- template: template$v,
+ template: template$p,
className: '',
ui: {
container: '.container',
sliderHorizontal: '.horizontal.slider',
sliderVertical: '.vertical.slider',
@@ -7152,11 +7234,11 @@
save: function save(coord, value) {
this.model.setFilePosition(this.options.propertyName, coord, Math.min(100, Math.max(0, value)));
}
});
- function template$w(data) {
+ function template$q(data) {
var __t, __p = '';
__p += '<div class="box">\n <h2>' +
((__t = ( I18n.t('pageflow.editor.templates.background_positioning.title') )) == null ? '' : __t) +
'</h2>\n <p>' +
((__t = ( I18n.t('pageflow.editor.templates.background_positioning.help') )) == null ? '' : __t) +
@@ -7169,11 +7251,11 @@
'</a>\n </div>\n</div>\n';
return __p
}
var BackgroundPositioningView = Marionette.ItemView.extend({
- template: template$w,
+ template: template$q,
className: 'background_positioning dialog',
mixins: [dialogView],
ui: {
previews: '.previews > div',
wrapper: '.wrapper'
@@ -7223,20 +7305,18 @@
BackgroundPositioningView.open = function (options) {
app.dialogRegion.show(new BackgroundPositioningView(options));
};
- function template$x(data) {
+ function template$r(data) {
var __p = '';
__p += '<div class="label"></div>\n<a href="#"></a>\n';
return __p
}
- /** @api private */
-
var DropDownButtonItemView = Marionette.ItemView.extend({
- template: template$x,
+ template: template$r,
tagName: 'li',
className: 'drop_down_button_item',
ui: {
link: '> a',
label: '> .label'
@@ -7270,12 +7350,10 @@
this.$el.toggleClass('is_checked', !!this.model.get('checked'));
this.$el.data('name', this.model.get('name'));
}
});
- /** @api private */
-
var DropDownButtonItemListView = function DropDownButtonItemListView(options) {
return new CollectionView({
tagName: 'ul',
className: 'drop_down_button_items',
collection: options.items,
@@ -7284,19 +7362,21 @@
listView: DropDownButtonItemListView
}
});
};
- function template$y(data) {
+ function template$s(data) {
var __p = '';
__p += '<button></button>\n\n<div class="drop_down_button_menu">\n</div>\n';
return __p
}
/**
* A button that displays a drop down menu on hover.
*
+ * @param {Object} options
+ *
* @param {String} options.label
* Button text.
*
* @param {Backbone.Collection} options.items
* Collection of menu items. See below for supported attributes.
@@ -7314,15 +7394,14 @@
*
* If the menu item model provdised a `selected` method, it is called
* when the menu item is clicked.
*
* @class
- * @memberof module:pageflow/editor
*/
var DropDownButtonView = Marionette.ItemView.extend({
- template: template$y,
+ template: template$s,
className: 'drop_down_button',
ui: {
button: '> button',
menu: '.drop_down_button_menu'
},
@@ -7385,11 +7464,62 @@
scheduleHideMenu: function scheduleHideMenu() {
this.hideMenuTimeout = setTimeout(_$1.bind(this.hideMenu, this), 300);
}
});
- function template$z(data) {
+ function template$t(data) {
+ var __p = '';
+ __p += '<div class="pictogram"></div>\n';
+ return __p
+ }
+
+ var FileThumbnailView = Marionette.ItemView.extend({
+ className: 'file_thumbnail',
+ template: template$t,
+ modelEvents: {
+ 'change:state': 'update'
+ },
+ ui: {
+ pictogram: '.pictogram'
+ },
+ onRender: function onRender() {
+ this.update();
+ },
+ update: function update() {
+ if (this.model) {
+ var stage = this.model.currentStage();
+
+ if (stage) {
+ this.setStageClassName(stage.get('name'));
+ this.ui.pictogram.toggleClass('action_required', stage.get('action_required'));
+ this.ui.pictogram.toggleClass('failed', stage.get('failed'));
+ } else {
+ this.ui.pictogram.removeClass(this.model.stages.pluck('name').join(' '));
+ }
+
+ this.ui.pictogram.addClass(this.model.thumbnailPictogram);
+ this.$el.css('background-image', this._imageUrl() ? 'url(' + this._imageUrl() + ')' : '');
+ this.$el.removeClass('empty').toggleClass('always_picogram', !!this.model.thumbnailPictogram).toggleClass('ready', this.model.isReady());
+ } else {
+ this.$el.css('background-image', '');
+ this.$el.removeClass('ready');
+ this.ui.pictogram.addClass('empty');
+ }
+ },
+ setStageClassName: function setStageClassName(name) {
+ if (!this.$el.hasClass(name)) {
+ this.ui.pictogram.removeClass('empty');
+ this.ui.pictogram.removeClass(this.model.stages.pluck('name').join(' '));
+ this.ui.pictogram.addClass(name);
+ }
+ },
+ _imageUrl: function _imageUrl() {
+ return this.model.get(this.options.imageUrlPropertyName || 'thumbnail_url');
+ }
+ });
+
+ function template$u(data) {
var __t, __p = '';
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="file_thumbnail"></div>\n<div class="file_name"></div>\n\n<a href="" class="unset" title="' +
((__t = ( I18n.t('pageflow.ui.templates.inputs.file_input.reset') )) == null ? '' : __t) +
'"></a>\n<a href="" class="choose" title="' +
((__t = ( I18n.t('pageflow.ui.templates.inputs.file_input.edit') )) == null ? '' : __t) +
@@ -7399,16 +7529,15 @@
/**
* Input view to reference a file.
*
* @class
- * @memberof module:pageflow/editor
*/
var FileInputView = Marionette.ItemView.extend({
mixins: [inputView],
- template: template$z,
+ template: template$u,
className: 'file_input',
ui: {
fileName: '.file_name',
thumbnail: '.file_thumbnail'
},
@@ -7576,18 +7705,18 @@
getDefaultTextTrackFile: function getDefaultTextTrackFile() {
return this.options.inputModel.getReference(this.options.propertyName, this.options.textTrackFiles);
}
});
- function template$A(data) {
+ function template$v(data) {
var __p = '';
__p += '<div class="spinner">\n <div class="rect1"></div>\n <div class="rect2"></div>\n <div class="rect3"></div>\n <div class="rect4"></div>\n <div class="rect5"></div>\n</div>\n';
return __p
}
var LoadingView = Marionette.ItemView.extend({
- template: template$A,
+ template: template$v,
className: 'loading',
tagName: 'li'
});
var selectableView = {
@@ -7606,23 +7735,21 @@
this.options.selection.set(this.selectionAttribute, null);
}
}
};
- function template$B(data) {
+ function template$w(data) {
var __t, __p = '';
__p += '<span class="theme_name"></span>\n<span class="button_or_checkmark">\n <p class="theme_in_use"></p>\n <a class="use_theme">' +
((__t = ( I18n.t('pageflow.editor.templates.theme.use') )) == null ? '' : __t) +
'</a>\n</span>\n';
return __p
}
- /** @api private */
-
var ThemeItemView = Marionette.ItemView.extend({
tagName: 'li',
- template: template$B,
+ template: template$w,
className: 'theme_item',
mixins: [selectableView],
selectionAttribute: 'theme',
ui: {
themeName: '.theme_name',
@@ -7649,11 +7776,11 @@
inUse: function inUse() {
return this.model.get('name') === this.options.themeInUse;
}
});
- function template$C(data) {
+ function template$x(data) {
var __t, __p = '';
__p += '<div class="box">\n <div class="content">\n <div>\n <h2 class="themes_header">' +
((__t = ( I18n.t('pageflow.editor.templates.change_theme_dialog.header') )) == null ? '' : __t) +
'</h2>\n <div class="themes_panel">\n </div>\n <div class="preview_panel">\n <h2 class="preview_header">' +
((__t = ( I18n.t('pageflow.editor.templates.change_theme_dialog.preview_header_prefix') )) == null ? '' : __t) +
@@ -7664,11 +7791,11 @@
'\n </a>\n </div>\n</div>\n';
return __p
}
var ChangeThemeDialogView = Marionette.ItemView.extend({
- template: template$C,
+ template: template$x,
className: 'change_theme dialog editor',
mixins: [dialogView],
ui: {
content: '.content',
themesPanel: '.themes_panel',
@@ -7733,28 +7860,98 @@
});
app.dialogRegion.show(view.render());
}).promise();
};
- function template$D(data) {
+ function template$y(data) {
var __p = '';
+ __p += '\n';
+ return __p
+ }
+
+ var StaticThumbnailView = Marionette.ItemView.extend({
+ template: template$y,
+ className: 'static_thumbnail',
+ modelEvents: {
+ 'change:configuration': 'update'
+ },
+ onRender: function onRender() {
+ this.update();
+ },
+ update: function update() {
+ this.$el.css('background-image', 'url(' + this._imageUrl() + ')');
+ },
+ _imageUrl: function _imageUrl() {
+ return this.model.thumbnailUrl();
+ }
+ });
+
+ /**
+ * Base thumbnail view for models supporting a `thumbnailFile` method.
+ *
+ * @class
+ */
+
+ var ModelThumbnailView = Marionette.View.extend({
+ className: 'model_thumbnail',
+ modelEvents: {
+ 'change:configuration': 'update'
+ },
+ render: function render() {
+ this.update();
+ return this;
+ },
+ update: function update() {
+ if (this.model) {
+ if (_$1.isFunction(this.model.thumbnailFile)) {
+ var file = this.model && this.model.thumbnailFile();
+
+ if (this.thumbnailView && this.currentFileThumbnail == file) {
+ return;
+ }
+
+ this.currentFileThumbnail = file;
+ this.newThumbnailView = new FileThumbnailView({
+ model: file,
+ className: 'thumbnail file_thumbnail',
+ imageUrlPropertyName: this.options.imageUrlPropertyName
+ });
+ } else {
+ this.newThumbnailView = this.newThumbnailView || new StaticThumbnailView({
+ model: this.model
+ });
+ }
+ }
+
+ if (this.thumbnailView) {
+ this.thumbnailView.close();
+ }
+
+ if (this.model) {
+ this.thumbnailView = this.subview(this.newThumbnailView);
+ this.$el.append(this.thumbnailView.el);
+ }
+ }
+ });
+
+ function template$z(data) {
+ var __p = '';
__p += '<label>\n <span class="name"></span>\n <span class="inline_help"></span>\n</label>\n<div class="title"></div>\n<button class="unset"></button>\n<button class="choose"></button>\n';
return __p
}
/**
* Base class for input views that reference models.
*
* @class
- * @memberof module:pageflow/editor
*/
var ReferenceInputView = Marionette.ItemView.extend(
- /** @lends module:pageflow/editor.ReferenceInputView# */
+ /** @lends ReferenceInputView.prototype */
{
mixins: [inputView],
- template: template$D,
+ template: template$z,
className: 'reference_input',
ui: {
title: '.title',
chooseButton: '.choose',
unsetButton: '.unset',
@@ -7849,11 +8046,11 @@
getTarget: function getTarget(themeName) {
return this.options.themes.findByName(themeName);
}
});
- function template$E(data) {
+ function template$A(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_meta_data.outline') )) == null ? '' : __t) +
'</a>\n\n<div class="failure">\n <p>' +
((__t = ( I18n.t('pageflow.editor.templates.edit_meta_data.save_error') )) == null ? '' : __t) +
@@ -7862,11 +8059,11 @@
'</a>\n</div>\n\n<div class="form_fields"></div>\n';
return __p
}
var EditMetaDataView = Marionette.Layout.extend({
- template: template$E,
+ template: template$A,
className: 'edit_meta_data',
mixins: [failureIndicatingView],
regions: {
formContainer: '.form_fields'
},
@@ -7874,87 +8071,79 @@
'click a.back': 'goBack'
},
onRender: function onRender() {
var entry = this.model;
var configurationEditor = new ConfigurationEditorView({
- model: entry.configuration,
+ model: entry.metadata.configuration,
tab: this.options.tab
});
configurationEditor.tab('general', function () {
this.input('title', TextInputView, {
- placeholder: entry.get('entry_title')
+ placeholder: entry.get('entry_title'),
+ model: entry.metadata
});
this.input('locale', SelectInputView, {
values: state.config.availablePublicLocales,
texts: _$1.map(state.config.availablePublicLocales, function (locale) {
return I18n$1.t('pageflow.public._language', {
locale: locale
});
- })
+ }),
+ model: entry.metadata
});
- this.input('credits', TextAreaInputView);
+ this.input('credits', TextAreaInputView, {
+ model: entry.metadata
+ });
this.input('author', TextInputView, {
- placeholder: state.config.defaultAuthorMetaTag
+ placeholder: state.config.defaultAuthorMetaTag,
+ model: entry.metadata
});
this.input('publisher', TextInputView, {
- placeholder: state.config.defaultPublisherMetaTag
+ placeholder: state.config.defaultPublisherMetaTag,
+ model: entry.metadata
});
this.input('keywords', TextInputView, {
- placeholder: state.config.defaultKeywordsMetaTag
+ placeholder: state.config.defaultKeywordsMetaTag,
+ model: entry.metadata
});
});
configurationEditor.tab('widgets', function () {
- var theme = entry.getTheme();
- this.input('manual_start', CheckBoxInputView);
- this.input('emphasize_chapter_beginning', CheckBoxInputView);
- this.input('emphasize_new_pages', CheckBoxInputView);
- this.input('home_button_enabled', CheckBoxInputView, {
- disabled: !theme.hasHomeButton(),
- displayUncheckedIfDisabled: true
- });
- this.input('overview_button_enabled', CheckBoxInputView, {
- disabled: !theme.hasOverviewButton(),
- displayUncheckedIfDisabled: true
- });
-
- if (theme.hasHomeButton()) {
- this.input('home_url', TextInputView, {
- placeholder: state.theming.get('pretty_url'),
- visibleBinding: 'home_button_enabled'
- });
- }
-
- this.view(EditWidgetsView, {
+ editor.entryType.appearanceInputs && editor.entryType.appearanceInputs(this, entry, state.theming);
+ entry.widgets && this.view(EditWidgetsView, {
model: entry,
widgetTypes: editor.widgetTypes
});
- if (pageflow.features.isEnabled('selectable_themes') && state.themes.length > 1) {
+ if (pageflow.features && pageflow.features.isEnabled('selectable_themes') && state.themes.length > 1) {
this.view(ThemeInputView, {
themes: state.themes,
propertyName: 'theme_name'
});
}
});
configurationEditor.tab('social', function () {
this.input('share_image_id', FileInputView, {
collection: state.imageFiles,
- fileSelectionHandler: 'entryConfiguration'
+ fileSelectionHandler: 'entryMetadata',
+ model: entry.metadata
});
this.input('summary', TextAreaInputView, {
disableRichtext: true,
- disableLinks: true
+ disableLinks: true,
+ model: entry.metadata
});
this.input('share_url', TextInputView, {
- placeholder: state.entry.get('pretty_url')
+ placeholder: state.entry.get('pretty_url'),
+ model: entry.metadata
});
this.input('share_providers', CheckBoxGroupInputView, {
values: state.config.availableShareProviders,
- translationKeyPrefix: 'activerecord.values.pageflow/entry.share_providers'
+ translationKeyPrefix: 'activerecord.values.pageflow/entry.share_providers',
+ model: entry.metadata
});
});
- this.listenTo(entry.configuration, 'change:theme_name', function () {
+ this.listenTo(entry.metadata, 'change:theme_name', function () {
configurationEditor.refresh();
});
this.formContainer.show(configurationEditor);
},
goBack: function goBack() {
@@ -7962,22 +8151,22 @@
trigger: true
});
}
});
- function template$F(data) {
+ function template$B(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_page_link.back') )) == null ? '' : __t) +
'</a>\n<a class="destroy">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_page_link.destroy') )) == null ? '' : __t) +
'</a>\n<div class="form_container"></div>\n';
return __p
}
var EditPageLinkView = Marionette.Layout.extend({
- template: template$F,
+ template: template$B,
regions: {
formContainer: '.form_container'
},
ui: {
backButton: 'a.back'
@@ -8012,11 +8201,11 @@
trigger: true
});
}
});
- function template$G(data) {
+ function template$C(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_page.outline') )) == null ? '' : __t) +
'</a>\n<a class="destroy">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_page.destroy') )) == null ? '' : __t) +
@@ -8027,11 +8216,11 @@
'</a>\n</div>\n\n<div class="page_type"></div>\n\n<div class="configuration_container"></div>';
return __p
}
var EditPageView = Marionette.Layout.extend({
- template: template$G,
+ template: template$C,
className: 'edit_page',
mixins: [failureIndicatingView],
regions: {
pageTypeContainer: '.page_type',
configurationContainer: '.configuration_container'
@@ -8081,17 +8270,10 @@
trigger: true
});
}
});
- /**
- * Input view to reference a page.
- *
- * @class
- * @memberof module:pageflow/editor
- */
-
var PageLinkInputView = ReferenceInputView.extend({
choose: function choose() {
return editor.selectPage({
isAllowed: this.options.isAllowed
});
@@ -8099,11 +8281,11 @@
getTarget: function getTarget(permaId) {
return state.pages.getByPermaId(permaId);
}
});
- function template$H(data) {
+ function template$D(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_storyline.outline') )) == null ? '' : __t) +
'</a>\n<a class="destroy" data-tooltip-align="bottom right">\n ' +
((__t = ( I18n.t('pageflow.editor.templates.edit_storyline.destroy') )) == null ? '' : __t) +
@@ -8114,11 +8296,11 @@
'</a>\n</div>\n\n<div class="form_container"></div>\n';
return __p
}
var EditStorylineView = Marionette.Layout.extend({
- template: template$H,
+ template: template$D,
className: 'edit_storyline',
mixins: [failureIndicatingView, tooltipContainer],
regions: {
formContainer: '.form_container'
},
@@ -8197,20 +8379,20 @@
trigger: true
});
}
});
- function template$I(data) {
+ function template$E(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.edit_widget.back') )) == null ? '' : __t) +
'</a>\n';
return __p
}
var EditWidgetView = Marionette.ItemView.extend({
- template: template$I,
+ template: template$E,
className: 'edit_widget',
events: {
'click a.back': function clickABack() {
editor.navigate('/meta_data/widgets', {
trigger: true
@@ -8231,19 +8413,26 @@
});
this.appendSubview(configurationEditor);
}
});
- function template$J(data) {
+ var loadable = modelLifecycleTrackingView({
+ classNames: {
+ creating: 'creating',
+ destroying: 'destroying'
+ }
+ });
+
+ function template$F(data) {
var __p = '';
__p += '<span class="file_thumbnail"></span>\n\n<span class="file_name"></span>\n';
return __p
}
var ExplorerFileItemView = Marionette.ItemView.extend({
tagName: 'li',
- template: template$J,
+ template: template$F,
mixins: [loadable, selectableView],
selectionAttribute: 'file',
ui: {
fileName: '.file_name',
thumbnail: '.file_thumbnail'
@@ -8276,18 +8465,18 @@
isDisabled: function isDisabled() {
return this.options.disabledIds && _$1.contains(this.options.disabledIds, this.model.get('id'));
}
});
- function template$K(data) {
+ function template$G(data) {
var __p = '';
__p += '<a href="">\n <span class="title"></span>\n</a>\n';
return __p
}
var OtherEntryItemView = Marionette.ItemView.extend({
- template: template$K,
+ template: template$G,
className: 'other_entry_item',
tagName: 'li',
mixins: [selectableView],
ui: {
title: '.title'
@@ -8298,11 +8487,11 @@
onRender: function onRender() {
this.ui.title.text(this.model.titleOrSlug());
}
});
- function template$L(data) {
+ function template$H(data) {
var __t, __p = '';
__p +=
((__t = ( I18n.t('pageflow.editor.templates.other_entries_blank_slate.none_available') )) == null ? '' : __t) +
'\n';
return __p
@@ -8324,22 +8513,22 @@
itemViewConstructor: OtherEntryItemView,
itemViewOptions: {
selection: this.options.selection
},
blankSlateViewConstructor: Marionette.ItemView.extend({
- template: template$L,
+ template: template$H,
tagName: 'li',
className: 'blank_slate'
}),
loadingViewConstructor: LoadingView
}));
this.otherEntries.fetch();
return this;
}
});
- function template$M(data) {
+ function template$I(data) {
var __t, __p = '';
__p += '<div class="box">\n <h2>' +
((__t = ( I18n.t('pageflow.editor.templates.files_explorer.reuse_files') )) == null ? '' : __t) +
'</h2>\n\n <div class="panels">\n <ul class="entries_panel">\n </ul>\n\n <div class="files_panel">\n </div>\n </div>\n\n <div class="footer">\n <button class="ok">' +
((__t = ( I18n.t('pageflow.editor.templates.files_explorer.ok') )) == null ? '' : __t) +
@@ -8364,11 +8553,11 @@
'<li>\n';
return __p
}
var FilesExplorerView = Marionette.ItemView.extend({
- template: template$M,
+ template: template$I,
className: 'files_explorer editor dialog',
mixins: [dialogView],
ui: {
entriesPanel: '.entries_panel',
filesPanel: '.files_panel',
@@ -8451,19 +8640,19 @@
FilesExplorerView.open = function (options) {
app.dialogRegion.show(new FilesExplorerView(options));
};
- function template$N(data) {
+ function template$J(data) {
var __p = '';
__p += '<th></th>\n<td></td>';
return __p
}
var FileMetaDataItemView = Marionette.ItemView.extend({
tagName: 'tr',
- template: template$N,
+ template: template$J,
ui: {
label: 'th',
value: 'td'
},
onRender: function onRender() {
@@ -8473,28 +8662,28 @@
name: this.options.name
}, this.options.valueViewOptions || {})));
this.ui.label.text(this.labelText());
},
labelText: function labelText() {
- return attributeTranslation(this.options.name, 'label', {
+ return i18nUtils.attributeTranslation(this.options.name, 'label', {
prefixes: ['pageflow.editor.files.attributes.' + this.model.fileType().collectionName, 'pageflow.editor.files.common_attributes'],
fallbackPrefix: 'activerecord.attributes',
fallbackModelI18nKey: this.model.i18nKey
});
}
});
- function template$O(data) {
+ function template$K(data) {
var __p = '';
__p += '<p class="percent"></p>\n<p class="description"></p>\n<p class="error_message"></p>';
return __p
}
var FileStageItemView = Marionette.ItemView.extend({
tagName: 'li',
className: 'file_stage_item',
- template: template$O,
+ template: template$K,
ui: {
description: '.description',
percent: '.percent',
errorMessage: '.error_message'
},
@@ -8531,11 +8720,11 @@
defaultValue: this.model.get('error_message')
});
}
});
- function template$P(data) {
+ function template$L(data) {
var __t, __p = '';
__p += '<span class="file_thumbnail"></span>\n\n<span class="file_name"></span>\n<a class="select">' +
((__t = ( I18n.t('pageflow.editor.templates.file_item.select') )) == null ? '' : __t) +
'</a>\n\n<div class="actions">\n <a class="settings" title="' +
((__t = ( I18n.t('pageflow.editor.templates.file_item.settings') )) == null ? '' : __t) +
@@ -8555,11 +8744,11 @@
return __p
}
var FileItemView = Marionette.ItemView.extend({
tagName: 'li',
- template: template$P,
+ template: template$L,
mixins: [loadable],
ui: {
fileName: '.file_name',
selectButton: '.select',
settingsButton: '.settings',
@@ -8670,11 +8859,11 @@
retry: function retry() {
this.model.retry();
}
});
- function template$Q(data) {
+ function template$M(data) {
var __t, __p = '';
__p += '<div class="filtered_files-banner">\n <span class="filtered_files-banner_prefix">\n ' +
((__t = ( I18n.t('pageflow.editor.views.filtered_files_view.banner_prefix') )) == null ? '' : __t) +
'\n </span>\n <span class="filtered_files-filter_name"></span>\n <a href=""\n class="filtered_files-reset_filter"\n title="' +
((__t = ( I18n.t('pageflow.editor.views.filtered_files_view.reset_filter') )) == null ? '' : __t) +
@@ -8689,11 +8878,11 @@
'</li>\n';
return __p
}
var FilteredFilesView = Marionette.ItemView.extend({
- template: template$Q,
+ template: template$M,
className: 'filtered_files',
ui: {
banner: '.filtered_files-banner',
filterName: '.filtered_files-filter_name'
},
@@ -8744,30 +8933,30 @@
this.ui.filterName.text(this.filterTranslation('name'));
}
},
filterTranslation: function filterTranslation(keyName, options) {
var filterName = this.options.filterName;
- return findTranslation(['pageflow.editor.files.filters.' + this.options.fileType.collectionName + '.' + filterName + '.' + keyName, 'pageflow.editor.files.common_filters.' + keyName], options);
+ return i18nUtils.findTranslation(['pageflow.editor.files.filters.' + this.options.fileType.collectionName + '.' + filterName + '.' + keyName, 'pageflow.editor.files.common_filters.' + keyName], options);
},
onClose: function onClose() {
if (this.filteredCollection) {
this.filteredCollection.dispose();
}
}
});
- function template$R(data) {
+ function template$N(data) {
var __t, __p = '';
__p += '<div class="box choose_importer_box">\n <h1 class="dialog-header">' +
((__t = ( I18n.t('pageflow.editor.views.files_view.importer.heading') )) == null ? '' : __t) +
'</h1>\n\n <div class="content">\n <ul class="importers_panel">\n </ul>\n </div>\n\n <div class="footer">\n <button class="close">' +
((__t = ( I18n.t('pageflow.editor.templates.files_explorer.cancel') )) == null ? '' : __t) +
'</button>\n </div>\n</div>\n';
return __p
}
- function template$S(data) {
+ function template$O(data) {
var __t, __p = '';
__p += '<button class=\'importer\' data-key=\'' +
((__t = ( data.fileImporter.key )) == null ? '' : __t) +
'\'>\n <div class="logo">\n <img alt="Free high resolution images" src="' +
((__t = ( data.fileImporter.logoSource )) == null ? '' : __t) +
@@ -8778,11 +8967,11 @@
'</p>\n </div>\n</button>';
return __p
}
var ImporterSelectView = Marionette.ItemView.extend({
- template: template$S,
+ template: template$O,
className: 'importer_select',
tagName: 'li',
events: {
'click .importer': function clickImporter(event) {
this.options.parentView.importerSelected(this.options.importer);
@@ -8795,11 +8984,11 @@
};
}
});
var ChooseImporterView = Marionette.ItemView.extend({
- template: template$R,
+ template: template$N,
className: 'choose_importer editor dialog',
mixins: [dialogView],
ui: {
importersList: '.importers_panel',
closeButton: '.close'
@@ -8830,11 +9019,11 @@
ChooseImporterView.open = function (options) {
app.dialogRegion.show(new ChooseImporterView(options).render());
};
- function template$T(data) {
+ function template$P(data) {
var __t, __p = '';
__p += '<div class="box file_importer_box">\n <h1 class="dialog-header">' +
((__t = ( I18n.t('pageflow.editor.file_importers.'+data.importerKey+'.dialog_label') )) == null ? '' : __t) +
'</h1>\n\n <div class="content_panel">\n \n </div>\n\n <div class="footer">\n <div class="disclaimer">\n <p>' +
((__t = ( I18n.t('pageflow.editor.file_importers.'+data.importerKey+'.disclaimer') )) == null ? '' : __t) +
@@ -8844,11 +9033,11 @@
((__t = ( I18n.t('pageflow.editor.templates.files_explorer.cancel') )) == null ? '' : __t) +
'</button>\n </div>\n</div>\n';
return __p
}
- function template$U(data) {
+ function template$Q(data) {
var __t, __p = '';
__p += '<div class="box">\n <h1 class="dialog-header">' +
((__t = ( I18n.t('pageflow.editor.templates.confirm_upload.header') )) == null ? '' : __t) +
'</h1>\n <p class="dialog-hint">' +
((__t = ( I18n.t('pageflow.editor.templates.confirm_upload.hint') )) == null ? '' : __t) +
@@ -8860,18 +9049,18 @@
((__t = ( I18n.t('pageflow.editor.templates.confirm_upload.close') )) == null ? '' : __t) +
'</button>\n </div>\n</div>\n';
return __p
}
- function template$V(data) {
+ function template$R(data) {
var __p = '';
__p += '<h2></h2>\n';
return __p
}
var UploadableFilesView = Marionette.ItemView.extend({
- template: template$V,
+ template: template$R,
className: 'uploadable_files',
ui: {
header: 'h2'
},
initialize: function initialize() {
@@ -8913,11 +9102,11 @@
});
}
});
var ConfirmFileImportUploadView = Marionette.Layout.extend({
- template: template$U,
+ template: template$Q,
className: 'confirm_upload editor dialog',
mixins: [dialogView],
regions: {
selectedFileRegion: '.selected_file_region'
},
@@ -8987,11 +9176,11 @@
ConfirmFileImportUploadView.open = function (options) {
app.dialogRegion.show(new ConfirmFileImportUploadView(options));
};
var FilesImporterView = Marionette.ItemView.extend({
- template: template$T,
+ template: template$P,
className: 'files_importer editor dialog',
mixins: [dialogView],
ui: {
contentPanel: '.content_panel',
spinner: '.lds-spinner',
@@ -9074,20 +9263,20 @@
FilesImporterView.open = function (options) {
app.dialogRegion.show(new FilesImporterView(options).render());
};
- function template$W(data) {
+ function template$S(data) {
var __t, __p = '';
__p += '<button class="">\n <span class="label">' +
((__t = ( I18n.t('pageflow.editor.templates.select_button.select') )) == null ? '' : __t) +
'</span>\n</button>\n\n<div class="dropdown">\n <ul class="dropdown-menu" role="menu">\n </ul>\n</div>\n';
return __p
}
var SelectButtonView = Marionette.ItemView.extend({
- template: template$W,
+ template: template$S,
className: 'select_button',
ui: {
button: 'button',
label: 'button .label',
menu: '.dropdown-menu',
@@ -9118,52 +9307,58 @@
addOption: function addOption(option, index) {
this.ui.menu.append('<li><a href="#" data-index="' + index + '">' + option.label + '</a></li>');
}
});
- function template$X(data) {
+ function template$T(data) {
var __t, __p = '';
__p += '<a class="back">' +
((__t = ( I18n.t('pageflow.editor.templates.files.back') )) == null ? '' : __t) +
'</a>\n';
return __p
}
var FilesView = Marionette.ItemView.extend({
- template: template$X,
+ template: template$T,
className: 'manage_files',
events: {
'click a.back': 'goBack',
'file-selected': 'updatePage'
},
onRender: function onRender() {
- this.addFileModel = new Backbone.Model({
- label: I18n$1.t('pageflow.editor.views.files_view.add'),
- options: [{
- label: I18n$1.t('pageflow.editor.views.files_view.upload'),
- handler: this.upload.bind(this)
- }, {
- label: I18n$1.t('pageflow.editor.views.files_view.reuse'),
- handler: function handler() {
- FilesExplorerView.open({
- callback: function callback(otherEntry, file) {
- state.entry.reuseFile(otherEntry, file);
- }
- });
- }
- }, {
+ var menuOptions = [{
+ label: I18n$1.t('pageflow.editor.views.files_view.upload'),
+ handler: this.upload.bind(this)
+ }, {
+ label: I18n$1.t('pageflow.editor.views.files_view.reuse'),
+ handler: function handler() {
+ FilesExplorerView.open({
+ callback: function callback(otherEntry, file) {
+ state.entry.reuseFile(otherEntry, file);
+ }
+ });
+ }
+ }];
+
+ if (editor.fileImporters.keys().length > 0) {
+ menuOptions.push({
label: I18n$1.t('pageflow.editor.views.files_view.import'),
handler: function handler() {
ChooseImporterView.open({
callback: function callback(importer) {
FilesImporterView.open({
importer: importer
});
}
});
}
- }]
+ });
+ }
+
+ this.addFileModel = new Backbone.Model({
+ label: I18n$1.t('pageflow.editor.views.files_view.add'),
+ options: menuOptions
});
this.$el.append(this.subview(new SelectButtonView({
model: this.addFileModel
})).el);
this.tabsView = new TabsView({
@@ -9206,18 +9401,18 @@
upload: function upload() {
app.trigger('request-upload');
}
});
- function template$Y(data) {
+ function template$U(data) {
var __p = '';
__p += '<div class="quota_state">\n</div>\n<div class="outlet">\n</div>\n<div class="exhausted_message">\n</div>\n';
return __p
}
var EntryPublicationQuotaDecoratorView = Marionette.Layout.extend({
- template: template$Y,
+ template: template$U,
className: 'quota_decorator',
regions: {
outlet: '.outlet'
},
ui: {
@@ -9254,11 +9449,11 @@
}
}
}
});
- function template$Z(data) {
+ function template$V(data) {
var __t, __p = '';
__p += '<div class="files_pending notice">\n <p>' +
((__t = ( I18n.t('pageflow.editor.templates.publish_entry.files_pending_notice') )) == null ? '' : __t) +
'</p>\n <p><a href="#files">' +
((__t = ( I18n.t('pageflow.editor.templates.publish_entry.show_files') )) == null ? '' : __t) +
@@ -9301,11 +9496,11 @@
'</p>\n <p><a href="" target="_blank"></a></p>\n</div>\n';
return __p
}
var PublishEntryView = Marionette.ItemView.extend({
- template: template$Z,
+ template: template$V,
className: 'publish_entry',
ui: {
publishUntilFields: '.publish_until_fields',
publishUntilField: 'input[name=publish_until]',
publishUntilTimeField: 'input[name=publish_until_time]',
@@ -9709,138 +9904,22 @@
_isChapterView: function _isChapterView() {
return !Backbone.history.getFragment();
}
});
- function template$_(data) {
+ function template$W(data) {
var __t, __p = '';
- __p += '<h2>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.header') )) == null ? '' : __t) +
- '</h2>\n<p>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.intro') )) == null ? '' : __t) +
- '</p>\n<ol>\n <li>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.create_chapter') )) == null ? '' : __t) +
- '</li>\n <li>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.create_page') )) == null ? '' : __t) +
- '</li>\n <li>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.edit_page') )) == null ? '' : __t) +
- '</li>\n</ol>\n<p>' +
- ((__t = ( I18n.t('pageflow.editor.blank_entry.outro') )) == null ? '' : __t) +
- '</p>\n';
- return __p
- }
-
- var BlankEntryView = Marionette.ItemView.extend({
- template: template$_,
- className: 'blank_entry'
- });
-
- var PagePreviewView = Marionette.View.extend({
- tagName: 'section',
- className: 'page',
- modelEvents: {
- 'change:template': 'updateTemplate',
- 'change:configuration': 'update',
- 'change:position': 'updatePositionClassNames',
- 'change:id': function changeId() {
- this.$el.attr('data-id', this.model.id);
- this.$el.attr('data-perma-id', this.model.get('perma_id'));
- this.$el.attr('id', this.model.get('perma_id'));
- }
- },
- events: {
- pageactivate: function pageactivate() {
- this.model.set('active', true);
- },
- pagedeactivate: function pagedeactivate() {
- this.model.set('active', false);
- }
- },
- render: function render() {
- this.$el.html(this.pageTemplate());
- this.$el.attr('data-id', this.model.id);
- this.$el.attr('data-perma-id', this.model.get('perma_id'));
- this.$el.attr('id', this.model.get('perma_id'));
- this.$el.attr('data-chapter-id', this.model.get('chapter_id'));
- this.$el.data('template', this.model.get('template'));
- this.$el.data('configuration', this.model.get('configuration'));
- this.$el.on('pageenhanced', _$1.bind(function () {
- this.update();
- this.initEmbeddedViews();
- this.$el.page('reactivate');
- }, this));
- return this;
- },
- onClose: function onClose() {
- this.$el.page('cleanup');
- },
- updateTemplate: function updateTemplate() {
- this.$el.page('cleanup');
- this.$el.html(this.pageTemplate());
- this.$el.data('template', this.model.get('template'));
- setTimeout(_$1.bind(function () {
- this.$el.page('reinit');
- }, this), 0);
- },
- update: function update() {
- this.$el.page('update', this.model.configuration);
- pageflow.events.trigger('page:update', this.model);
- this.refreshScroller();
- this.updatePositionClassNames();
- },
- updatePositionClassNames: function updatePositionClassNames() {
- this.$el.toggleClass('chapter_beginning', this.model.isChapterBeginning());
- this.$el.toggleClass('first_page', this.model.isFirstPage());
- },
- pageTypeHooks: function pageTypeHooks() {
- return pageflow.pageType.get(this.model.get('template'));
- },
- pageTemplate: function pageTemplate() {
- return this._unescape($('script[data-template="' + this.model.get('template') + '_page"]').html());
- },
- refreshScroller: function refreshScroller() {
- this.$el.page('refreshScroller');
- },
- initEmbeddedViews: function initEmbeddedViews() {
- var view = this;
-
- if (view.embeddedViews) {
- view.embeddedViews.call('close');
- }
-
- view.embeddedViews = new ChildViewContainer();
-
- _$1.each(view.embeddedViewDefinitions(), function (item, selector) {
- view.$(selector).each(function () {
- view.embeddedViews.add(new item.view(_$1.extend(item.options || {}, {
- el: this,
- model: view.model.configuration,
- container: view
- })).render());
- });
- });
- },
- embeddedViewDefinitions: function embeddedViewDefinitions() {
- return _$1.extend({}, this.pageTypeHooks().embeddedEditorViews() || {}, this.model.pageType().embeddedViews());
- },
- _unescape: function _unescape(text) {
- return $('<div/>').html(text).text();
- }
- });
-
- function template$$(data) {
- var __t, __p = '';
__p += '<div class="box">\n <h2>' +
((__t = ( I18n.t('pageflow.editor.templates.help.title') )) == null ? '' : __t) +
'</h2>\n\n <div class="placeholder"></div>\n\n <div class="footer">\n <a class="close" href="">' +
((__t = ( I18n.t('pageflow.editor.templates.help.close') )) == null ? '' : __t) +
'</a>\n </div>\n</div>\n';
return __p
}
var HelpView = Marionette.ItemView.extend({
- template: template$$,
+ template: template$W,
className: 'help',
ui: {
placeholder: '.placeholder',
sections: 'section',
menuItems: 'li'
@@ -9909,22 +9988,26 @@
section.toggle(section.data('name') === name);
});
}
});
- function template$10(data) {
+ var PageThumbnailView = ModelThumbnailView.extend({
+ className: 'model_thumbnail page_thumbnail'
+ });
+
+ function template$X(data) {
var __t, __p = '';
__p += '<div>\n <span class="missing_page_thumbnail"></span>\n <span class="page_thumbnail"></span>\n <div class="title"></div>\n <div class="label"></div>\n <a class="remove" title="' +
((__t = ( I18n.t('pageflow.editor.templates.page_link_item.remove') )) == null ? '' : __t) +
'"></a>\n <a class="edit" title="' +
((__t = ( I18n.t('pageflow.editor.templates.page_link_item.edit') )) == null ? '' : __t) +
'"></a>\n<div>\n';
return __p
}
var PageLinkItemView = Marionette.ItemView.extend({
- template: template$10,
+ template: template$X,
tagName: 'li',
className: 'page_link',
ui: {
thumbnail: '.page_thumbnail',
title: '.title',
@@ -9970,22 +10053,22 @@
this.ui.editButton.toggle(!!this.model.editPath());
this.$el.toggleClass('dangling', !page);
}
});
- function template$11(data) {
+ function template$Y(data) {
var __t, __p = '';
__p += '<label>\n <span class="name">' +
((__t = ( I18n.t('pageflow.editor.templates.page_links.label') )) == null ? '' : __t) +
'</span>\n</label>\n<ul class="links outline"></ul>\n\n<a href="" class="add_link">' +
((__t = ( I18n.t('pageflow.editor.templates.page_links.add') )) == null ? '' : __t) +
'</a>\n';
return __p
}
var PageLinksView = Marionette.ItemView.extend({
- template: template$11,
+ template: template$Y,
className: 'page_links',
ui: {
links: 'ul.links',
addButton: '.add_link'
},
@@ -10017,11 +10100,11 @@
updateAddButton: function updateAddButton(pageLinks) {
this.ui.addButton.css('display', pageLinks.canAddLink() ? 'inline-block' : 'none');
}
});
- function template$12(data) {
+ function template$Z(data) {
var __t, __p = '';
__p += '<div class="emulation_mode_button-menu">\n <div class="emulation_mode_button-menu_header">\n ' +
((__t = ( I18n.t('pageflow.editor.templates.emulation_mode_button.header') )) == null ? '' : __t) +
'\n </div>\n <ul>\n <li class="emulation_mode_button-menu_item emulation_mode_button-desktop">\n <a class="emulation_mode_button-menu_link">\n ' +
((__t = ( I18n.t('pageflow.editor.templates.emulation_mode_button.desktop') )) == null ? '' : __t) +
@@ -10036,11 +10119,11 @@
'\n</div>\n';
return __p
}
var EmulationModeButtonView = Marionette.ItemView.extend({
- template: template$12,
+ template: template$Z,
className: 'emulation_mode_button',
ui: {
phoneItem: '.emulation_mode_button-phone',
desktopItem: '.emulation_mode_button-desktop',
phoneDisplay: '.emulation_mode_button-display.emulation_mode_button-phone',
@@ -10049,41 +10132,41 @@
events: {
'click .emulation_mode_button-desktop a': function clickEmulation_mode_buttonDesktopA() {
this.model.unset('emulation_mode');
},
'click .emulation_mode_button-phone a': function clickEmulation_mode_buttonPhoneA() {
- if (!this.model.get('current_page_supports_emulation_mode')) {
+ if (this.model.get('emulation_mode_disabled')) {
return;
}
this.model.set('emulation_mode', 'phone');
}
},
modelEvents: {
- 'change:emulation_mode change:current_page_supports_emulation_mode': 'update'
+ 'change:emulation_mode change:emulation_mode_disabled': 'update'
},
onRender: function onRender() {
this.update();
},
update: function update() {
- this.ui.phoneItem.toggleClass('disabled', !this.model.get('current_page_supports_emulation_mode'));
+ this.ui.phoneItem.toggleClass('disabled', !!this.model.get('emulation_mode_disabled'));
this.ui.phoneItem.toggleClass('active', this.model.has('emulation_mode'));
this.ui.desktopItem.toggleClass('active', !this.model.has('emulation_mode'));
this.ui.phoneDisplay.toggleClass('active', this.model.has('emulation_mode'));
this.ui.desktopDisplay.toggleClass('active', !this.model.has('emulation_mode'));
}
});
- function template$13(data) {
+ function template$_(data) {
var __t, __p = '';
__p +=
((__t = ( I18n.t('pageflow.editor.templates.help_button.open_help') )) == null ? '' : __t);
return __p
}
var HelpButtonView = Marionette.ItemView.extend({
- template: template$13,
+ template: template$_,
className: 'help_button',
events: {
'click': function click() {
app.trigger('toggle-help');
}
@@ -10091,181 +10174,21 @@
});
var SidebarFooterView = Marionette.View.extend({
className: 'sidebar_footer',
render: function render() {
- if (pageflow.features.isEnabled('editor_emulation_mode')) {
+ if (this.model.supportsPhoneEmulation()) {
this.appendSubview(new EmulationModeButtonView({
model: this.model
}));
}
this.appendSubview(new HelpButtonView());
return this;
}
});
- function template$14(data) {
- var __t, __p = '';
- __p += '<div class="container">\n <div class="header"></div>\n <div class="overview"></div>\n\n <div class="entry"></div>\n</div>\n<div class="navigation_disabled_hint">\n ' +
- ((__t = ( I18n.t('pageflow.editor.templates.entry_preview.navigation_disabled_hint') )) == null ? '' : __t) +
- '\n</div>\n';
- return __p
- }
-
- var EntryPreviewView = Marionette.ItemView.extend({
- template: template$14,
- className: 'entry_preview',
- ui: {
- container: '> .container',
- header: '> .container > .header',
- entry: '> .container > .entry',
- overview: '> .container > .overview',
- navigationDisabledHint: '.navigation_disabled_hint'
- },
- initialize: function initialize() {
- this.pages = this.model.pages.persisted();
- this.widgets = $();
- this.debouncedFetchWidgets = _$1.debounce(this.fetchWidgets, 200);
- },
- onRender: function onRender() {
- this.pageViews = this.subview(new CollectionView({
- el: this.ui.entry,
- collection: this.pages,
- itemViewConstructor: PagePreviewView,
- blankSlateViewConstructor: BlankEntryView
- }));
- this.ui.entry.append($('#indicators_seed > *'));
- this.update();
- this.listenTo(state.entry, 'sync:order sync:widgets', this.update);
- this.listenTo(state.entry, 'change:configuration', function () {
- state.entry.once('sync', this.update, this);
- });
- this.listenTo(state.entry, 'change:emulation_mode', this.updateEmulationMode);
- this.listenTo(state.storylines, 'sync', this.update);
- this.listenTo(state.chapters, 'sync', this.update);
- this.listenTo(state.pages, 'sync', this.update);
- this.listenTo(state.audioFiles, 'sync', this.update);
- this.listenTo(state.imageFiles, 'sync', this.update);
- this.listenTo(state.videoFiles, 'sync', this.update);
- this.listenTo(pageflow.events, 'page:changing', function (event) {
- if (state.entry.get('emulation_mode')) {
- this.ui.navigationDisabledHint.css('opacity', 1);
- clearTimeout(this.navigationDisabledHintTimeout);
- this.navigationDisabledHintTimeout = setTimeout(_$1.bind(function () {
- this.ui.navigationDisabledHint.css('opacity', 0);
- }, this), 2000);
- event.cancel();
- }
- });
- this.listenTo(pageflow.events, 'page:change', function (page) {
- this.updateEmulationModeSupport(page.getPermaId());
- });
- },
- onShow: function onShow() {
- var slideshow = pageflow.Slideshow.setup({
- element: this.ui.entry,
- enabledFeatureNames: state.entry.get('enabled_feature_names'),
- simulateHistory: true
- });
- pageflow.delayedStart.perform();
- this.listenTo(this.pages, 'add', function () {
- slideshow.update();
- });
- this.listenTo(this.pages, 'remove', function () {
- slideshow.update();
- });
- this.listenTo(this.pages, 'edit', function (model) {
- if (this.lastEditedPage != model) {
- state.entry.unset('emulation_mode');
- }
-
- this.lastEditedPage = model;
- slideshow.goTo(this.pageViews.itemViews.findByModel(model).$el);
- });
- this.listenTo(app, 'resize', function () {
- slideshow.triggerResizeHooks();
- this.updateSimulatedMediaQueryClasses();
- });
- this.listenTo(state.pages, 'change:template', function () {
- this.updateEmulationModeSupport(slideshow.currentPagePermaId());
- });
- this.updateSimulatedMediaQueryClasses();
- },
- updateEmulationModeSupport: function updateEmulationModeSupport(permaId) {
- var model = state.pages.getByPermaId(permaId);
- state.entry.set('current_page_supports_emulation_mode', model && model.pageType().supportsPhoneEmulation());
- },
- updateSimulatedMediaQueryClasses: function updateSimulatedMediaQueryClasses() {
- var width = this.ui.container.width();
- var height = this.ui.container.height();
- var portrait = width < height;
- $('html').toggleClass('simulate_mobile', width <= 900).toggleClass('simulate_phone', portrait && width <= 500 || !portrait && height <= 500).toggleClass('simulate_desktop', portrait && width > 500 || !portrait && height > 500).toggleClass('simulate_narrow_desktop', width <= 1200).toggleClass('simulate_wide_desktop', width > 1600).toggleClass('simulate_pad_portrait', width <= 768 && portrait).toggleClass('simulate_phone_portrait', width <= 500 && portrait);
- },
- update: function update() {
- this.debouncedFetchWidgets();
- this.$el.toggleClass('emphasize_chapter_beginning', !!this.model.configuration.get('emphasize_chapter_beginning'));
- },
- fetchWidgets: function fetchWidgets() {
- var view = this;
- $.ajax(this.model.url() + '/partials').success(function (response) {
- var partials = $('<div />').html(response);
- view.ui.header.replaceWith(partials.find('> .header'));
- view.ui.overview.replaceWith(partials.find('> .overview'));
- view.bindUIElements();
- view.updateWidgets(partials);
- view.ui.header.header({
- slideshow: pageflow.slides
- });
- view.ui.overview.overview();
- });
- },
- updateWidgets: function updateWidgets(partials) {
- var widgets = partials.find('[data-widget]');
- this.updatePresentWidgetsCssClasses(widgets);
- this.widgets.remove();
- this.widgets = widgets;
- this.ui.entry.before(this.widgets);
- pageflow.widgetTypes.enhance(this.$el);
- },
- updatePresentWidgetsCssClasses: function updatePresentWidgetsCssClasses(newWidgets) {
- var previousClasses = this.widgetNames(this.widgets);
- var newClasses = this.widgetNames(newWidgets);
-
- var removedClasses = _$1.difference(previousClasses, newClasses);
-
- var addedClasses = _$1.difference(newClasses, previousClasses);
-
- this.$el.addClass('widgets_present');
- this.$el.removeClass(removedClasses.join(' '));
- this.$el.addClass(addedClasses.join(' '));
-
- if (removedClasses.length || addedClasses.length) {
- pageflow.events.trigger('widgets:update');
- }
- },
- widgetNames: function widgetNames(widgets) {
- return widgets.map(function () {
- return 'widget_' + $(this).data('widget') + '_present';
- }).get();
- },
- updateEmulationMode: function updateEmulationMode() {
- if (state.entry.previous('emulation_mode')) {
- this.$el.removeClass(this.emulationModeClassName(state.entry.previous('emulation_mode')));
- }
-
- if (state.entry.get('emulation_mode')) {
- this.$el.addClass(this.emulationModeClassName(state.entry.get('emulation_mode')));
- }
-
- app.trigger('resize');
- },
- emulationModeClassName: function emulationModeClassName(mode) {
- return 'emulation_mode_' + mode;
- }
- });
-
var HelpImageView = Marionette.View.extend({
tagName: 'img',
className: 'help_image',
render: function render() {
this.$el.attr('src', state.editorAssetUrls.help[this.options.imageName]);
@@ -10279,77 +10202,22 @@
this.$el.html(this.options.text);
return this;
}
});
- function template$15(data) {
+ function template$$(data) {
var __t, __p = '';
- __p += '<div class="box">\n <h2>' +
- ((__t = ( I18n.t('pageflow.editor.templates.page_selection.title') )) == null ? '' : __t) +
- '</h2>\n\n <div class="wrapper editor">\n <div class="storyline_picker">\n </div>\n </div>\n\n <div class="footer">\n <a href="" class="close">' +
- ((__t = ( I18n.t('pageflow.editor.templates.page_selection.cancel') )) == null ? '' : __t) +
- '</a>\n </div>\n</div>\n';
- return __p
- }
-
- var PageSelectionView = Marionette.ItemView.extend({
- template: template$15,
- className: 'page_selection dialog',
- mixins: [dialogView],
- ui: {
- storylines: '.storyline_picker',
- chapters: '.chapters'
- },
- events: {
- 'click ul.pages li': function clickUlPagesLi(event) {
- this.options.onSelect(state.pages.get($(event.currentTarget).data('id')));
- this.close();
- }
- },
- onRender: function onRender() {
- var options = this.options;
- this.subview(new StorylinePickerView({
- el: this.ui.storylines,
- pageItemViewOptions: {
- isDisabled: function isDisabled(page) {
- return options.isAllowed && !options.isAllowed(page);
- }
- }
- }));
- }
- });
-
- PageSelectionView.selectPage = function (options) {
- return $.Deferred(function (deferred) {
- var view = new PageSelectionView({
- model: state.entry,
- onSelect: deferred.resolve,
- isAllowed: options && options.isAllowed
- });
- view.on('close', function () {
- deferred.reject();
- });
- app.dialogRegion.show(view.render());
- }).promise();
- };
-
- editor.pageSelectionView = PageSelectionView;
-
- function template$16(data) {
- var __t, __p = '';
__p += '<span class="list_item_thumbnail"></span>\n<span class="list_item_missing_thumbnail"></span>\n<span class="list_item_type_pictogram type_pictogram"></span>\n\n<div class="list_item_title"></div>\n<div class="list_item_description"></div>\n\n<div class="list_item_buttons">\n <a class="list_item_edit_button" title="' +
((__t = ( I18n.t('pageflow.editor.templates.list_item.edit') )) == null ? '' : __t) +
'"></a>\n <a class="list_item_remove_button" title="' +
((__t = ( I18n.t('pageflow.editor.templates.list_item.remove') )) == null ? '' : __t) +
'"></a>\n</div>\n';
return __p
}
- /** @api private */
-
var ListItemView = Marionette.ItemView.extend({
- template: template$16,
+ template: template$$,
tagName: 'li',
className: 'list_item',
ui: {
thumbnail: '.list_item_thumbnail',
typePictogram: '.list_item_type_pictogram',
@@ -10419,11 +10287,11 @@
getOptionResult: function getOptionResult(name) {
return typeof this.options[name] === 'function' ? this.options[name](this.model) : this.options[name];
}
});
- function template$17(data) {
+ function template$10(data) {
var __t, __p = '';
__p += '<div class="checking notice">\n <p>' +
((__t = ( I18n.t('pageflow.editor.templates.locked.loading') )) == null ? '' : __t) +
'</p>\n\n <a class="close" href="#">' +
((__t = ( I18n.t('pageflow.editor.templates.locked.close') )) == null ? '' : __t) +
@@ -10434,11 +10302,11 @@
'</a>\n</div>\n\n';
return __p
}
var LockedView = Marionette.ItemView.extend({
- template: template$17,
+ template: template$10,
className: 'locked checking',
ui: {
breakButton: '.break',
message: '.error .message'
},
@@ -10511,10 +10379,11 @@
togglerTip_closed: I18n$1.t('pageflow.editor.views.editor_views.show_editor'),
togglerTip_open: I18n$1.t('pageflow.editor.views.editor_views.hide_editor'),
resizerTip: I18n$1.t('pageflow.editor.views.editor_views.resize_editor'),
enableCursorHotkey: false,
fxName: 'none',
+ maskIframesOnResize: true,
onresize: function onresize() {
app.trigger('resize');
}
});
new UploaderView().render();
@@ -10626,11 +10495,11 @@
}
}
}
});
- function template$18(data) {
+ function template$11(data) {
var __t, __p = '';
__p += '<li class="uploading"><span class="count">0</span>' +
((__t = ( I18n.t('pageflow.editor.templates.notification.upload_pending') )) == null ? '' : __t) +
'</li>\n<li class="failed"><span class="count">0</span> <span class="description">' +
((__t = ( I18n.t('pageflow.editor.templates.notification.save_error') )) == null ? '' : __t) +
@@ -10649,11 +10518,11 @@
}
var NotificationsView = Marionette.ItemView.extend({
className: 'notifications',
tagName: 'ul',
- template: template$18,
+ template: template$11,
ui: {
failedCount: '.failed .count',
uploadingCount: '.uploading .count',
confirmableFilesCount: '.confirmable_files .count'
},
@@ -10663,20 +10532,20 @@
}
},
onRender: function onRender() {
this.listenTo(state.entry, 'change:uploading_files_count', this.notifyUploadCount);
this.listenTo(state.entry, 'change:confirmable_files_count', this.notifyConfirmableFilesCount);
- this.listenTo(state.savingRecords, 'add', this.update);
- this.listenTo(state.savingRecords, 'remove', this.update);
+ this.listenTo(editor.savingRecords, 'add', this.update);
+ this.listenTo(editor.savingRecords, 'remove', this.update);
this.listenTo(editor.failures, 'add', this.update);
this.listenTo(editor.failures, 'remove', this.update);
this.update();
this.notifyConfirmableFilesCount();
},
update: function update() {
this.$el.toggleClass('failed', !editor.failures.isEmpty());
- this.$el.toggleClass('saving', !state.savingRecords.isEmpty());
+ this.$el.toggleClass('saving', !editor.savingRecords.isEmpty());
this.ui.failedCount.text(editor.failures.count());
},
notifyUploadCount: function notifyUploadCount(model, uploadCount) {
this.$el.toggleClass('uploading', uploadCount > 0);
this.ui.uploadingCount.text(uploadCount);
@@ -10736,18 +10605,18 @@
_getFile: function _getFile() {
return this.model.getReference(this.options.propertyName, this.options.collection);
}
});
- function template$19(data) {
+ function template$12(data) {
var __p = '';
__p += '<h2></h2>\n';
return __p
}
var NestedFilesView = Marionette.ItemView.extend({
- template: template$19,
+ template: template$12,
className: 'nested_files',
ui: {
header: 'h2'
},
initialize: function initialize() {
@@ -10819,22 +10688,22 @@
this.options.selection.set('nextFile', undefined);
}
}, 200)
});
- function template$1a(data) {
+ function template$13(data) {
var __t, __p = '';
__p += '<div class="text_tracks_container">\n <div class="files_upload_panel">\n <div class="files_panel">\n </div>\n <a class="upload" href="">' +
((__t = ( I18n.t('pageflow.editor.templates.text_tracks.upload') )) == null ? '' : __t) +
'</a>\n </div>\n\n <div class="selected_file_panel">\n <h2 class="selected_file_header">' +
((__t = ( I18n.t('pageflow.editor.templates.text_tracks.edit_file_header') )) == null ? '' : __t) +
'</h2>\n <div class="selected_file_region">\n </div>\n </div>\n</div>\n';
return __p
}
var TextTracksView = Marionette.Layout.extend({
- template: template$1a,
+ template: template$13,
className: 'text_tracks',
regions: {
selectedFileRegion: '.selected_file_region'
},
ui: {
@@ -10907,19 +10776,19 @@
this.$el.show();
});
this.listenTo(pageflow.events, 'atmo:enabled', function () {
this.$el.hide();
});
- this.$el.toggle(pageflow.atmo.disabled);
+ this.$el.toggle(!!pageflow.atmo && pageflow.atmo.disabled);
},
render: function render() {
this.$el.attr('title', I18n$1.t('pageflow.editor.atmo.disabled'));
return this;
}
});
- function template$1b(data) {
+ function template$14(data) {
var __p = '';
__p += '<label>\n <span class="list_label"></span>\n</label>\n\n<ul class="list_items"></ul>\n';
return __p
}
@@ -10937,10 +10806,12 @@
*
* Models inside the collection must implement the following methods:
*
* @param {Backbone.Collection} options.collection
*
+ * @param {Object} options
+ *
* @param {string} options.label
* Text of the label to display above the list.
*
* @param {boolean} [options.highlight=false]
*
@@ -10957,15 +10828,14 @@
* @param {function} [options.onEdit]
*
* @param {function} [options.onRemove]
*
* @class
- * @memberof module:pageflow/editor
*/
var ListView = Marionette.ItemView.extend({
- template: template$1b,
+ template: template$14,
className: 'list',
ui: {
label: '.list_label',
items: '.list_items'
},
@@ -10991,11 +10861,11 @@
this.$el.toggleClass('with_type_pictogram', !!this.options.itemTypeName);
}
});
var ConfirmUploadView = Marionette.Layout.extend({
- template: template$U,
+ template: template$Q,
className: 'confirm_upload editor dialog',
mixins: [dialogView],
regions: {
selectedFileRegion: '.selected_file_region'
},
@@ -11050,10 +10920,104 @@
ConfirmUploadView.open = function (options) {
app.dialogRegion.show(new ConfirmUploadView(options));
};
+ /**
+ * Base view to edit configuration container models. Extend and
+ * override the `configure` method which receives a {@link
+ * ConfigurationEditorView} to define the tabs and inputs that shall
+ * be displayed.
+ *
+ * Add a `translationKeyPrefix` property to the prototype and define
+ * the following translations:
+ *
+ * * `<translationKeyPrefix>.tabs`: used as `tabTranslationKeyPrefix`
+ * of the `ConfigurationEditorView`.
+ *
+ * * `<translationKeyPrefix>.attributes`: used as one of the
+ * `attributeTranslationKeyPrefixes` of the
+ * `ConfigurationEditorView`.
+ *
+ * * `<translationKeyPrefix>.back` (optional): Back button label.
+ *
+ * * `<translationKeyPrefix>.destroy` (optional): Destroy button
+ * label.
+ *
+ * * `<translationKeyPrefix>.confirm_destroy` (optional): Confirm
+ * message displayed before destroying.
+ *
+ * * `<translationKeyPrefix>.save_error` (optional): Header of the
+ * failure message that is displayed if the model cannot be saved.
+ *
+ * * `<translationKeyPrefix>.retry` (optional): Label of the retry
+ * button of the failure message.
+ *
+ * @param {Object} options
+ * @param {Backbone.Model} options.model -
+ * Model including the {@link configurationContainer},
+ * {@link failureTracking} and {@link delayedDestroying} mixins.
+ *
+ * @since 15.1
+ */
+
+ var EditConfigurationView = Marionette.Layout.extend({
+ template: function template(_ref) {
+ var t = _ref.t;
+ 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 ");
+ },
+ serializeData: function serializeData() {
+ var _this = this;
+
+ return {
+ t: function t(key) {
+ return _this.t(key);
+ }
+ };
+ },
+ mixins: [failureIndicatingView],
+ regions: {
+ configurationContainer: '.configuration_container'
+ },
+ events: {
+ 'click a.back': 'goBack',
+ 'click a.destroy': 'destroy'
+ },
+ onRender: function onRender() {
+ var translationKeyPrefix = _$1.result(this, 'translationKeyPrefix');
+
+ this.configurationEditor = new ConfigurationEditorView({
+ tabTranslationKeyPrefix: "".concat(translationKeyPrefix, ".tabs"),
+ attributeTranslationKeyPrefixes: ["".concat(translationKeyPrefix, ".attributes")],
+ model: this.model.configuration
+ });
+ this.configure(this.configurationEditor);
+ this.configurationContainer.show(this.configurationEditor);
+ },
+ onShow: function onShow() {
+ this.configurationEditor.refreshScroller();
+ },
+ destroy: function destroy() {
+ if (window.confirm(this.t('confirm_destroy'))) {
+ this.model.destroyWithDelay();
+ this.goBack();
+ }
+ },
+ goBack: function goBack() {
+ editor.navigate('/', {
+ trigger: true
+ });
+ },
+ t: function t(suffix) {
+ var translationKeyPrefix = _$1.result(this, 'translationKeyPrefix');
+
+ return I18n$1.t("".concat(translationKeyPrefix, ".").concat(suffix), {
+ defaultValue: I18n$1.t("pageflow.editor.views.edit_configuration.".concat(suffix))
+ });
+ }
+ });
+
ConfigurationEditorView.register('audio', {
configure: function configure() {
this.tab('general', function () {
this.group('general', {
supportsTextPositionCenter: true
@@ -11353,11 +11317,11 @@
this.tab('loading_spinner', function () {
this.view(InfoBoxView, {
text: I18n$1.t('pageflow.editor.title_loading_spinner.widget_type_info_box_text')
});
this.input('title', TextInputView, {
- placeholder: state.entry.configuration.get('title') || state.entry.get('entry_title')
+ placeholder: state.entry.metadata.get('title') || state.entry.get('entry_title')
});
this.input('subtitle', TextInputView);
this.input('custom_background_image_id', FileInputView, {
collection: 'image_files',
fileSelectionHandler: 'widgetConfiguration'
@@ -11531,11 +11495,11 @@
});
state.themes = new ThemesCollection(options.themes);
state.pages = new PagesCollection(options.pages);
state.chapters = new ChaptersCollection(options.chapters);
state.storylines = new StorylinesCollection(options.storylines);
- state.entry = new Entry(options.entry, {
+ state.entry = editor.createEntryModel(options, {
widgets: widgets
});
state.theming = new Theming(options.theming);
state.account = new Backbone.Model(options.account);
widgets.subject = state.entry;
@@ -11555,13 +11519,12 @@
state.storylines.saveOrder();
}, 100));
editor.failures.watch(state.entry);
editor.failures.watch(state.pages);
editor.failures.watch(state.chapters);
- state.savingRecords = new SavingRecordsCollection();
- state.savingRecords.watch(state.pages);
- state.savingRecords.watch(state.chapters);
+ editor.savingRecords.watch(state.pages);
+ editor.savingRecords.watch(state.chapters);
pageflow.events.trigger('seed:loaded');
});
app.addInitializer(function (options) {
state.fileUploader = new FileUploader({
@@ -11614,11 +11577,11 @@
}
});
state.entry.on('use:files', function () {
pageflow.stylesheet.reload('entry');
});
- state.entry.configuration.on('change:theme_name', function () {
+ state.entry.metadata.on('change:theme_name', function () {
var theme = state.entry.getTheme();
pageflow.stylesheet.update('theme', theme.get('stylesheet_path'));
});
});
@@ -11671,11 +11634,11 @@
}).render();
new ScrollingView({
el: $('sidebar .scrolling'),
region: app.sidebarRegion
}).render();
- app.previewRegion.show(new EntryPreviewView({
+ app.previewRegion.show(new editor.entryType.previewView({
model: state.entry
}));
app.indicatorsRegion.show(new DisabledAtmoIndicatorView());
app.notificationsRegion.show(new NotificationsView());
app.sidebarFooterRegion.show(new SidebarFooterView({
@@ -11699,15 +11662,13 @@
exports.BackButtonDecoratorView = BackButtonDecoratorView;
exports.BackgroundImageEmbeddedView = BackgroundImageEmbeddedView;
exports.BackgroundPositioningPreviewView = BackgroundPositioningPreviewView;
exports.BackgroundPositioningSlidersView = BackgroundPositioningSlidersView;
exports.BackgroundPositioningView = BackgroundPositioningView;
- exports.BlankEntryView = BlankEntryView;
exports.ChangeThemeDialogView = ChangeThemeDialogView;
exports.Chapter = Chapter;
exports.ChapterConfiguration = ChapterConfiguration;
- exports.ChapterItemView = ChapterItemView;
exports.ChapterPagesCollection = ChapterPagesCollection;
exports.ChapterScaffold = ChapterScaffold;
exports.ChaptersCollection = ChaptersCollection;
exports.CheckBoxGroupInputView = CheckBoxGroupInputView;
exports.CheckBoxInputView = CheckBoxInputView;
@@ -11725,10 +11686,11 @@
exports.DisabledAtmoIndicatorView = DisabledAtmoIndicatorView;
exports.DropDownButtonItemListView = DropDownButtonItemListView;
exports.DropDownButtonItemView = DropDownButtonItemView;
exports.DropDownButtonView = DropDownButtonView;
exports.EditChapterView = EditChapterView;
+ exports.EditConfigurationView = EditConfigurationView;
exports.EditEntryView = EditEntryView;
exports.EditFileView = EditFileView;
exports.EditLock = EditLock;
exports.EditLockContainer = EditLockContainer;
exports.EditMetaDataView = EditMetaDataView;
@@ -11741,18 +11703,18 @@
exports.EditorView = EditorView;
exports.EmulationModeButtonView = EmulationModeButtonView;
exports.EncodedFile = EncodedFile;
exports.EncodingConfirmation = EncodingConfirmation;
exports.Entry = Entry;
- exports.EntryConfiguration = EntryConfiguration;
- exports.EntryConfigurationFileSelectionHandler = EntryConfigurationFileSelectionHandler;
- exports.EntryPreviewView = EntryPreviewView;
+ exports.EntryMetadata = EntryMetadata;
+ exports.EntryMetadataFileSelectionHandler = EntryMetadataFileSelectionHandler;
exports.EntryPublication = EntryPublication;
exports.EntryPublicationQuotaDecoratorView = EntryPublicationQuotaDecoratorView;
exports.EnumTableCellView = EnumTableCellView;
exports.ExplorerFileItemView = ExplorerFileItemView;
exports.ExtendedSelectInputView = ExtendedSelectInputView;
+ exports.Failure = Failure;
exports.FileConfiguration = FileConfiguration;
exports.FileImport = FileImport;
exports.FileInputView = FileInputView;
exports.FileItemView = FileItemView;
exports.FileMetaDataItemValueView = FileMetaDataItemValueView;
@@ -11761,17 +11723,19 @@
exports.FileReuse = FileReuse;
exports.FileSettingsDialogView = FileSettingsDialogView;
exports.FileStage = FileStage;
exports.FileStageItemView = FileStageItemView;
exports.FileThumbnailView = FileThumbnailView;
+ exports.FileTypes = FileTypes;
exports.FileTypesCollection = FileTypesCollection;
exports.FileUploader = FileUploader;
exports.FilesCollection = FilesCollection;
exports.FilesExplorerView = FilesExplorerView;
exports.FilesImporterView = FilesImporterView;
exports.FilesView = FilesView;
exports.FilteredFilesView = FilteredFilesView;
+ exports.ForeignKeySubsetCollection = ForeignKeySubsetCollection;
exports.HelpButtonView = HelpButtonView;
exports.HelpImageView = HelpImageView;
exports.HelpView = HelpView;
exports.IconTableCellView = IconTableCellView;
exports.ImageFile = ImageFile;
@@ -11782,13 +11746,10 @@
exports.ListItemView = ListItemView;
exports.ListView = ListView;
exports.LoadingView = LoadingView;
exports.LockedView = LockedView;
exports.ModelThumbnailView = ModelThumbnailView;
- exports.MultiCollection = MultiCollection;
- exports.NavigatableChapterItemView = NavigatableChapterItemView;
- exports.NavigatablePageItemView = NavigatablePageItemView;
exports.NestedFilesCollection = NestedFilesCollection;
exports.NestedFilesView = NestedFilesView;
exports.NestedTypeError = NestedTypeError;
exports.NotificationsView = NotificationsView;
exports.Object = BaseObject;
@@ -11797,29 +11758,25 @@
exports.OtherEntriesCollectionView = OtherEntriesCollectionView;
exports.OtherEntry = OtherEntry;
exports.OtherEntryItemView = OtherEntryItemView;
exports.Page = Page;
exports.PageConfigurationFileSelectionHandler = PageConfigurationFileSelectionHandler;
- exports.PageItemView = PageItemView;
exports.PageLink = PageLink;
exports.PageLinkConfigurationEditorView = PageLinkConfigurationEditorView;
exports.PageLinkFileSelectionHandler = PageLinkFileSelectionHandler;
exports.PageLinkInputView = PageLinkInputView;
exports.PageLinkItemView = PageLinkItemView;
exports.PageLinksCollection = PageLinksCollection;
exports.PageLinksView = PageLinksView;
- exports.PagePreviewView = PagePreviewView;
- exports.PageSelectionView = PageSelectionView;
exports.PageThumbnailView = PageThumbnailView;
exports.PagesCollection = PagesCollection;
exports.PresenceTableCellView = PresenceTableCellView;
exports.PreviewEntryData = PreviewEntryData;
exports.ProxyUrlInputView = ProxyUrlInputView;
exports.PublishEntryView = PublishEntryView;
exports.ReferenceInputView = ReferenceInputView;
exports.ReusableFile = ReusableFile;
- exports.SavingRecordsCollection = SavingRecordsCollection;
exports.Scaffold = Scaffold;
exports.ScrollingView = ScrollingView;
exports.SelectButtonView = SelectButtonView;
exports.SelectInputView = SelectInputView;
exports.SidebarController = SidebarController;
@@ -11830,12 +11787,10 @@
exports.StaticThumbnailView = StaticThumbnailView;
exports.Storyline = Storyline;
exports.StorylineChaptersCollection = StorylineChaptersCollection;
exports.StorylineConfiguration = StorylineConfiguration;
exports.StorylineOrdering = StorylineOrdering;
- exports.StorylineOutlineView = StorylineOutlineView;
- exports.StorylinePickerView = StorylinePickerView;
exports.StorylineScaffold = StorylineScaffold;
exports.StorylineTransitiveChildPages = StorylineTransitiveChildPages;
exports.StorylinesCollection = StorylinesCollection;
exports.SubsetCollection = SubsetCollection;
exports.TableCellView = TableCellView;
@@ -11866,25 +11821,30 @@
exports.VideoFile = VideoFile;
exports.Widget = Widget;
exports.WidgetConfiguration = WidgetConfiguration;
exports.WidgetConfigurationFileSelectionHandler = WidgetConfigurationFileSelectionHandler;
exports.WidgetItemView = WidgetItemView;
+ exports.WidgetTypes = WidgetTypes;
exports.WidgetsCollection = WidgetsCollection;
exports.addAndReturnModel = addAndReturnModel;
exports.app = app;
exports.authenticationProvider = authenticationProvider;
+ exports.configurationContainer = configurationContainer;
+ exports.cssModulesUtils = cssModulesUtils;
exports.delayedDestroying = delayedDestroying;
exports.dialogView = dialogView;
exports.editor = editor;
+ exports.entryTypeEditorControllerUrls = entryTypeEditorControllerUrls;
exports.failureIndicatingView = failureIndicatingView;
exports.failureTracking = failureTracking;
exports.fileWithType = fileWithType;
exports.filesCountWatcher = filesCountWatcher;
exports.formDataUtils = formDataUtils;
exports.i18nUtils = i18nUtils;
exports.inputView = inputView;
exports.inputWithPlaceholderText = inputWithPlaceholderText;
exports.loadable = loadable;
+ exports.modelLifecycleTrackingView = modelLifecycleTrackingView;
exports.orderedCollection = orderedCollection;
exports.persistedPromise = persistedPromise;
exports.polling = polling;
exports.retryable = retryable;
exports.selectableView = selectableView;