forked from 0x2620/pandora
391 lines
16 KiB
JavaScript
391 lines
16 KiB
JavaScript
'use strict';
|
|
|
|
pandora.UI = (function() {
|
|
|
|
var self = {}, that = {};
|
|
|
|
self.previousUI = {};
|
|
|
|
that.encode = function(val) {
|
|
return val.replace(/\./g, '\\.');
|
|
};
|
|
|
|
that.getPrevious = function(key) {
|
|
// fixme: probably unneeded by now
|
|
return !key ? self.previousUI : self.previousUI[key];
|
|
};
|
|
|
|
that.reset = function() {
|
|
pandora.api.resetUI({}, function() {
|
|
pandora.user.ui = pandora.site.user.ui;
|
|
pandora.user.ui._list = pandora.getListState(
|
|
pandora.user.ui.find
|
|
);
|
|
pandora.user.ui._filterState = pandora.getFilterState(
|
|
pandora.user.ui.find
|
|
);
|
|
pandora.user.ui._documentFilterState = pandora.getDocumentFilterState(
|
|
pandora.user.ui.findDocuments
|
|
);
|
|
pandora.user.ui._findState = pandora.getFindState(
|
|
pandora.user.ui.find
|
|
);
|
|
pandora.user.ui._collection = pandora.getCollectionState(
|
|
pandora.user.ui.findDocuments
|
|
);
|
|
pandora.user.ui._findDocumentsState = pandora.getFindDocumentsState(
|
|
pandora.user.ui.findDocuments
|
|
);
|
|
Ox.Theme(pandora.user.ui.theme);
|
|
pandora.$ui.appPanel.reload();
|
|
});
|
|
};
|
|
|
|
// sets pandora.user.ui.key to val
|
|
// key foo.bar.baz sets pandora.user.ui.foo.bar.baz
|
|
// val null removes a key
|
|
that.set = function(/* {key: val}[, flag] or key, val[, flag] */) {
|
|
|
|
var add = {},
|
|
args,
|
|
collection,
|
|
collectionView,
|
|
collectionSettings = pandora.site.collectionSettings,
|
|
editSettings = pandora.site.editSettings,
|
|
item,
|
|
list,
|
|
listSettings = pandora.site.listSettings,
|
|
listView,
|
|
set = {},
|
|
textSettings = pandora.site.textSettings,
|
|
trigger = {},
|
|
triggerEvents;
|
|
|
|
if (Ox.isObject(arguments[0])) {
|
|
args = arguments[0];
|
|
triggerEvents = Ox.isUndefined(arguments[1]) ? true : arguments[1];
|
|
} else {
|
|
args = Ox.makeObject([arguments[0], arguments[1]]);
|
|
triggerEvents = Ox.isUndefined(arguments[2]) ? true : arguments[1];
|
|
}
|
|
|
|
Ox.Log('UI', 'SET', JSON.stringify(args));
|
|
|
|
self.previousUI = Ox.clone(pandora.user.ui, true);
|
|
self.previousUI._list = pandora.getListState(self.previousUI.find);
|
|
|
|
if (args.section == 'texts') {
|
|
trigger.section = args.section;
|
|
trigger.text = args.text;
|
|
} else if (args.section == 'edits') {
|
|
trigger.section = args.section;
|
|
trigger.edit = args.edit;
|
|
} else if (pandora.user.ui.section == 'documents' || args.section == 'documents') {
|
|
if ('findDocuments' in args) {
|
|
// the challenge here is that find may change list,
|
|
// and list may then change listSort and listView,
|
|
// which we don't want to trigger, since find triggers
|
|
// (values we put in add will be changed, but won't trigger)
|
|
collection = pandora.getCollectionState(args.findDocuments);
|
|
pandora.user.ui._collection = collection;
|
|
pandora.user.ui._documentFilterState = pandora.getDocumentFilterState(args.findDocuments);
|
|
pandora.user.ui._findDocumentsState = pandora.getFindDocumentsState(args.findDocuments);
|
|
if (pandora.$ui.appPanel && !pandora.stayInItemView) {
|
|
// if we're not on page load, and if find isn't a context change
|
|
// caused by an edit, then switch from item view to list view
|
|
args['document'] = '';
|
|
}
|
|
if (collection != self.previousUI._collection) {
|
|
Ox.Log('UI', 'FIND HAS CHANGED COLLECTION', self.previousUI._collection, '>', collection);
|
|
// if find has changed collection
|
|
Ox.forEach(collectionSettings, function(collectionSetting, setting) {
|
|
// then for each setting that corresponds to a collection setting
|
|
if (!Ox.isUndefined(args[setting])) {
|
|
add[setting] = args[setting];
|
|
} else if (
|
|
!pandora.user.ui.collections[collection]
|
|
|| Ox.isUndefined(pandora.user.ui.collections[collection][collectionSetting])
|
|
) {
|
|
// either add the default setting
|
|
add[setting] = pandora.site.user.ui[setting];
|
|
} else {
|
|
// or the existing collection setting
|
|
add[setting] = pandora.user.ui.collections[collection][collectionSetting];
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
collection = self.previousUI._collection;
|
|
}
|
|
if (!pandora.user.ui.collections[collection]) {
|
|
add['collections.' + that.encode(collection)] = {};
|
|
}
|
|
Ox.forEach(collectionSettings, function(collectionSetting, setting) {
|
|
// for each setting that corresponds to a collection setting
|
|
// set that collection setting to
|
|
var key = 'collections.' + that.encode(collection) + '.' + collectionSetting;
|
|
if (setting in args) {
|
|
// the setting passed to UI.set
|
|
add[key] = args[setting];
|
|
} else if (setting in add) {
|
|
// or the setting changed via find
|
|
add[key] = add[setting];
|
|
} else if (!pandora.user.ui.collections[collection]) {
|
|
// or the default setting
|
|
add[key] = pandora.site.user.ui[setting];
|
|
}
|
|
});
|
|
// set nested lisColumnWidth updates
|
|
Ox.forEach(args, function(value, key) {
|
|
if (Ox.startsWith(key, 'collectionColumnWidth.')) {
|
|
key = 'collections.' + that.encode(collection) + '.columnWidth.'
|
|
+ key.slice('collectionColumnWidth.'.length);
|
|
if (!(key in add)) {
|
|
add[key] = value;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (args.document) {
|
|
// when switching to an item, update list selection
|
|
add['collectionSelection'] = [args.document];
|
|
add['collections.' + that.encode(collection) + '.selection'] = [args.document];
|
|
}
|
|
} else {
|
|
if ('find' in args) {
|
|
// the challenge here is that find may change list,
|
|
// and list may then change listSort and listView,
|
|
// which we don't want to trigger, since find triggers
|
|
// (values we put in add will be changed, but won't trigger)
|
|
list = pandora.getListState(args.find);
|
|
pandora.user.ui._list = list;
|
|
pandora.user.ui._filterState = pandora.getFilterState(args.find);
|
|
pandora.user.ui._findState = pandora.getFindState(args.find);
|
|
if (pandora.$ui.appPanel && !pandora.stayInItemView) {
|
|
// if we're not on page load, and if find isn't a context change
|
|
// caused by an edit, then switch from item view to list view
|
|
args['item'] = '';
|
|
}
|
|
if (list != self.previousUI._list) {
|
|
Ox.Log('UI', 'FIND HAS CHANGED LIST')
|
|
// if find has changed list
|
|
Ox.forEach(listSettings, function(listSetting, setting) {
|
|
// then for each setting that corresponds to a list setting
|
|
if (!Ox.isUndefined(args[setting])) {
|
|
add[setting] = args[setting];
|
|
} else if (
|
|
!pandora.user.ui.lists[list]
|
|
|| Ox.isUndefined(pandora.user.ui.lists[list][listSetting])
|
|
) {
|
|
// either add the default setting
|
|
add[setting] = pandora.site.user.ui[setting];
|
|
} else {
|
|
// or the existing list setting
|
|
add[setting] = pandora.user.ui.lists[list][listSetting];
|
|
}
|
|
});
|
|
}
|
|
add.itemFind = pandora.getItemFind(args.find);
|
|
} else {
|
|
list = self.previousUI._list;
|
|
}
|
|
// it is important to check for find first, so that
|
|
// if find changes list, list is correct here
|
|
item = args.item || pandora.user.ui.item;
|
|
listView = add.listView || args.listView;
|
|
|
|
if (listView) {
|
|
if (pandora.isClipView(listView)) {
|
|
// when switching to a clip view, clear list selection
|
|
// (but don't trigger an additional event)
|
|
add.listSelection = [];
|
|
} else if (['text', 'position'].indexOf(
|
|
pandora.user.ui.listSort[0].key
|
|
) > -1) {
|
|
// when switching to a non-clip view, with a sort key
|
|
// that only exists in clip view, reset sort to default
|
|
args.listSort = pandora.site.user.ui.listSort;
|
|
}
|
|
}
|
|
|
|
if (!pandora.user.ui.lists[list]) {
|
|
add['lists.' + that.encode(list)] = {};
|
|
}
|
|
Ox.forEach(listSettings, function(listSetting, setting) {
|
|
// for each setting that corresponds to a list setting
|
|
// set that list setting to
|
|
var key = 'lists.' + that.encode(list) + '.' + listSetting;
|
|
if (setting in args) {
|
|
// the setting passed to UI.set
|
|
add[key] = args[setting];
|
|
} else if (setting in add) {
|
|
// or the setting changed via find
|
|
add[key] = add[setting];
|
|
} else if (!pandora.user.ui.lists[list]) {
|
|
// or the default setting
|
|
add[key] = pandora.site.user.ui[setting];
|
|
}
|
|
});
|
|
// set nested lisColumnWidth updates
|
|
Ox.forEach(args, function(value, key) {
|
|
if (Ox.startsWith(key, 'listColumnWidth.')) {
|
|
key = 'lists.' + that.encode(list) + '.columnWidth.'
|
|
+ key.slice('listColumnWidth.'.length);
|
|
if (!(key in add)) {
|
|
add[key] = value;
|
|
}
|
|
}
|
|
});
|
|
|
|
if (args.item) {
|
|
// when switching to an item, update list selection
|
|
add['listSelection'] = [args.item];
|
|
add['lists.' + that.encode(list) + '.selection'] = [args.item];
|
|
if (
|
|
!args.itemView
|
|
&& ['timeline', 'player', 'editor'].indexOf(
|
|
pandora.user.ui.itemView
|
|
) > -1
|
|
&& !pandora.user.ui.videoPoints[item]
|
|
&& !args['videoPoints.' + item]
|
|
) {
|
|
// if the item view doesn't change, remains a video view,
|
|
// video points don't exist yet, and won't be set,
|
|
// add default video points
|
|
add['videoPoints.' + item] = {
|
|
annotation: '',
|
|
'in': 0,
|
|
out: 0,
|
|
position: 0
|
|
};
|
|
}
|
|
if (args['videoPoints.' + item] && (
|
|
!pandora.user.ui.item
|
|
|| pandora.user.ui.itemView != 'editor'
|
|
)) {
|
|
pandora._dontSelectResult = true;
|
|
}
|
|
}
|
|
|
|
if (['timeline', 'player', 'editor'].indexOf(args.itemView) > -1) {
|
|
// when switching to a video view, add it as default video view
|
|
args.videoView = args.itemView;
|
|
if (
|
|
!pandora.user.ui.videoPoints[item]
|
|
&& !args['videoPoints.' + item]
|
|
) {
|
|
// if video points don't exist yet, and won't be set,
|
|
// add default video points
|
|
add['videoPoints.' + item] = {
|
|
annotation: '',
|
|
'in': 0,
|
|
out: 0,
|
|
position: 0
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
if (args.edit) {
|
|
// add local edit settings
|
|
if (!pandora.user.ui.edits[args.edit]) {
|
|
add['edits.' + that.encode(args.edit)] = {};
|
|
}
|
|
Ox.forEach(editSettings, function(value, key) {
|
|
var editsKey = 'edits.' + that.encode(args.edit) + '.' + key;
|
|
add[editsKey] = editsKey in args ? args[editsKey]
|
|
: (pandora.user.ui.edits[args.edit] && !Ox.isUndefined(
|
|
pandora.user.ui.edits[args.edit][key]
|
|
)) ? pandora.user.ui.edits[args.edit][key]
|
|
: value;
|
|
});
|
|
}
|
|
|
|
Ox.forEach({
|
|
editSelection: 'selection',
|
|
editSort: 'sort',
|
|
editView: 'view'
|
|
}, function(editSetting, setting) {
|
|
var key = 'edits.' + that.encode(
|
|
args.edit || pandora.user.ui.edit
|
|
) + '.' + editSetting;
|
|
if (setting in args) {
|
|
// add local edit setting
|
|
add[key] = args[setting];
|
|
} else if (setting in add) {
|
|
// add local edit setting
|
|
add[key] = add[setting];
|
|
} else if (key in add) {
|
|
// add global edit setting
|
|
add[setting] = add[key];
|
|
}
|
|
});
|
|
|
|
if (args.text) {
|
|
add['texts.' + that.encode(args.text)] = Ox.map(textSettings, function(value, key) {
|
|
var textsKey = 'texts.' + that.encode(args.text),
|
|
textsSubKey = textsKey + '.' + key;
|
|
return textsKey in args && key in args[textsKey] ? args[textsKey][key]
|
|
: textsSubKey in args ? args[textSubKey]
|
|
: (pandora.user.ui.texts[args.text] && !Ox.isUndefined(
|
|
pandora.user.ui.texts[args.text][key]
|
|
)) ? pandora.user.ui.texts[args.text][key]
|
|
: value;
|
|
});
|
|
}
|
|
|
|
// items in args trigger events, items in add do not
|
|
[args, add].forEach(function(obj, isAdd) {
|
|
Ox.forEach(obj, function(val, key) {
|
|
// make sure to not split at escaped dots ('\.')
|
|
var keys = key.replace(/\\\./g, '\n').split('.').map(function(key) {
|
|
return key.replace(/\n/g, '.')
|
|
}),
|
|
part,
|
|
ui = pandora.user.ui;
|
|
while (keys.length > 1) {
|
|
part = part ? part + '.' + keys[0] : keys[0];
|
|
if (Ox.isUndefined(ui[keys[0]])) {
|
|
ui[keys[0]] = {};
|
|
set[part] = {};
|
|
}
|
|
ui = ui[keys.shift()];
|
|
}
|
|
if (!Ox.isEqual(ui[keys[0]], val)) {
|
|
if (val === null) {
|
|
delete ui[keys[0]];
|
|
} else {
|
|
ui[keys[0]] = val;
|
|
}
|
|
set[key] = val;
|
|
if (!isAdd) {
|
|
trigger[key] = val;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
if (Ox.len(set) && !pandora.isEmbedURL() && !pandora.isPrintURL()) {
|
|
pandora.api.setUI(set);
|
|
}
|
|
triggerEvents && Ox.forEach(trigger, function(val, key) {
|
|
Ox.Log('UI', 'TRIGGER ', key, val);
|
|
Ox.forEach(pandora.$ui, function($element) {
|
|
if (Ox.UI.isElement($element)) {
|
|
$element.triggerEvent('pandora_' + key.toLowerCase(), {
|
|
value: val,
|
|
previousValue: self.previousUI[key]
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
pandora.URL.update(Object.keys(
|
|
!pandora.$ui.appPanel ? args : trigger
|
|
));
|
|
|
|
};
|
|
|
|
return that;
|
|
|
|
}());
|
|
|