', {'class': 'cp-dropdown-content'});
if (config.left) { $innerblock.addClass('cp-dropdown-left'); }
var hide = function () {
window.setTimeout(function () { $innerblock.hide(); }, 0);
};
var setOptions = function (options) {
options.forEach(function (o) {
if (!isValidOption(o)) { return; }
if (isElement(o)) { return $innerblock.append(o); }
var $el = $('<' + o.tag + '>', o.attributes || {});
if (typeof(o.content) === 'string' || (o.content instanceof Element)) {
o.content = [o.content];
}
if (Array.isArray(o.content)) {
o.content.forEach(function (item) {
if (item instanceof Element) {
return void $el.append(item);
}
if (typeof(item) === 'string') {
$el[0].appendChild(document.createTextNode(item));
}
});
// array of elements or text nodes
}
$el.appendTo($innerblock);
if (typeof(o.action) === 'function') {
$el.click(function (e) {
var close = o.action(e);
if (close) { hide(); }
});
}
});
};
setOptions(config.options);
$container.setOptions = function (options) {
$innerblock.empty();
setOptions(options);
};
$container.append($button).append($innerblock);
var value = config.initialValue || '';
var setActive = function ($el) {
if ($el.length !== 1) { return; }
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
$el.addClass('cp-dropdown-element-active');
var scroll = $el.position().top + $innerblock.scrollTop();
if (scroll < $innerblock.scrollTop()) {
$innerblock.scrollTop(scroll);
} else if (scroll > ($innerblock.scrollTop() + 280)) {
$innerblock.scrollTop(scroll-270);
}
};
var show = function () {
var wh = $(window).height();
var button = $button[0].getBoundingClientRect();
var topPos = button.bottom;
$innerblock.css('bottom', '');
if (config.noscroll) {
var h = $innerblock.outerHeight();
if ((topPos + h) > wh) {
$innerblock.css('bottom', button.height+'px');
}
} else {
$innerblock.css('max-height', Math.floor(wh - topPos - 1)+'px');
}
$innerblock.show();
$innerblock.find('.cp-dropdown-element-active').removeClass('cp-dropdown-element-active');
if (config.isSelect && value) {
var $val = $innerblock.find('[data-value="'+value+'"]');
setActive($val);
try {
$innerblock.scrollTop($val.position().top + $innerblock.scrollTop());
} catch (e) {}
}
if (config.feedback) { Feedback.send(config.feedback); }
};
$container.click(function (e) {
e.stopPropagation();
var state = $innerblock.is(':visible');
$('.cp-dropdown-content').hide();
var $c = $container.closest('.cp-toolbar-drawer-content');
$c.removeClass('cp-dropdown-visible');
if (!state) { $c.addClass('cp-dropdown-visible'); }
try {
$('iframe').each(function (idx, ifrw) {
$(ifrw).contents().find('.cp-dropdown-content').hide();
});
} catch (er) {
// empty try catch in case this iframe is problematic (cross-origin)
}
if (state) {
hide();
return;
}
show();
});
if (config.isSelect) {
var pressed = '';
var to;
$container.onChange = Util.mkEvent();
$container.on('click', 'a', function () {
value = $(this).data('value');
var $val = $(this);
var textValue = $val.text() || value;
$button.find('.cp-dropdown-button-title').text(textValue);
$container.onChange.fire(textValue, value);
});
$container.keydown(function (e) {
var $value = $innerblock.find('[data-value].cp-dropdown-element-active:visible');
if (!$value.length) {
$value = $innerblock.find('[data-value]').first();
}
if (e.which === 38) { // Up
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $prev = $value.prev();
$prev.mouseenter();
setActive($prev);
}
}
if (e.which === 40) { // Down
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.mouseleave();
var $next = $value.next();
$next.mouseenter();
setActive($next);
}
}
if (e.which === 13) { //Enter
e.preventDefault();
e.stopPropagation();
if ($value.length) {
$value.click();
hide();
}
}
if (e.which === 27) { // Esc
e.preventDefault();
e.stopPropagation();
$value.mouseleave();
hide();
}
});
$container.keypress(function (e) {
window.clearTimeout(to);
var c = String.fromCharCode(e.which);
pressed += c;
var $value = $innerblock.find('[data-value^="'+pressed+'"]:first');
if ($value.length) {
setActive($value);
$innerblock.scrollTop($value.position().top + $innerblock.scrollTop());
}
to = window.setTimeout(function () {
pressed = '';
}, 1000);
});
$container.setValue = function (val, name, sync) {
value = val;
var $val = $innerblock.find('[data-value="'+val+'"]');
var textValue = name || $val.text() || val;
var f = function () {
$button.find('.cp-dropdown-button-title').text(textValue);
};
if (sync) { return void f(); }
setTimeout(f);
};
$container.getValue = function () {
return typeof(value) === "undefined" ? '' : value;
};
}
return $container;
};
UIElements.displayInfoMenu = function (Common, metadataMgr) {
//var padType = metadataMgr.getMetadata().type;
var priv = metadataMgr.getPrivateData();
var origin = priv.origin;
// TODO link to the most recent changelog/release notes
// https://github.com/xwiki-labs/cryptpad/releases/latest/ ?
var template = function (line, link) {
if (!line || !link) { return; }
var p = $('
').html(line)[0]; // XXX
var sub = link.cloneNode(true);
// XXX use URL if you need to?
/* This is a hack to make relative URLs point to the main domain
instead of the sandbox domain. It will break if the admins have specified
some less common URL formats for their customizable links, such as if they've
used a protocal-relative absolute URL. The URL API isn't quite safe to use
because of IE (thanks, Bill). */
var href = sub.getAttribute('href');
if (/^\//.test(href)) { sub.setAttribute('href', origin + href); }
var a = p.querySelector('a');
if (!a) { return; }
sub.innerText = a.innerText;
p.replaceChild(sub, a);
return p;
};
var legalLine = template(Messages.info_imprintFlavour, Pages.imprintLink);
var privacyLine = template(Messages.info_privacyFlavour, Pages.privacyLink);
var faqLine = template(Messages.help_genericMore, Pages.docsLink);
var termsLine = template(Messages.info_termsFlavour, Pages.termsLink);
var sourceLine = template(Messages.info_sourceFlavour, Pages.sourceLink);
var content = h('div.cp-info-menu-container', [
h('div.logo-block', [
h('img', {
src: '/customize/CryptPad_logo.svg?' + urlArgs
}),
h('h6', "CryptPad"),
h('span', Pages.versionString)
]),
h('hr'),
h('p', Pages.hostDescription),
h('hr'),
faqLine,
termsLine,
privacyLine,
legalLine,
sourceLine,
]);
$(content).find('a').attr('target', '_blank');
var buttons = [
{
className: 'primary',
name: Messages.filePicker_close,
onClick: function () {},
keys: [27],
},
];
var modal = UI.dialog.customModal(content, {buttons: buttons });
UI.openCustomModal(modal);
};
UIElements.createUserAdminMenu = function (Common, config) {
var metadataMgr = Common.getMetadataMgr();
var displayNameCls = config.displayNameCls || 'cp-toolbar-user-name';
var priv = metadataMgr.getPrivateData();
var accountName = Util.fixHTML(priv.accountName);
var origin = priv.origin;
var padType = metadataMgr.getMetadata().type;
var options = [];
if (config.displayNameCls) {
var userAdminContent = [];
if (accountName) {
userAdminContent.push(h('span', [
Messages.user_accountName,
': ',
h('span', accountName),
]));
userAdminContent.push(h('br'));
}
if (config.displayName && !AppConfig.disableProfile) {
// Hide "Display name:" in read only mode
userAdminContent.push(h('span', [
Messages.user_displayName,
': ',
h('span', {
class: displayNameCls,
}),
]));
}
options.push({
tag: 'p',
attributes: {'class': 'cp-toolbar-account'},
content: userAdminContent,
});
}
if (accountName && !AppConfig.disableProfile) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-profile fa fa-user-circle'},
content: h('span', Messages.profileButton),
action: function () {
if (padType) {
Common.openURL(origin+'/profile/');
} else {
Common.gotoURL(origin+'/profile/');
}
},
});
}
if (padType !== 'drive' || (!accountName && priv.newSharedFolder)) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-hdd-o'
},
content: h('span', Messages.type.drive),
action: function () {
Common.openURL(origin+'/drive/');
},
});
}
if (padType !== 'teams' && accountName) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-users'
},
content: h('span', Messages.type.teams),
action: function () {
Common.openURL('/teams/');
},
});
}
if (padType !== 'calendar' && accountName) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-calendar',
},
content: h('span', Messages.calendar),
action: function () {
Common.openURL('/calendar/');
},
});
}
if (padType !== 'contacts' && accountName) {
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-address-book'
},
content: h('span', Messages.type.contacts),
action: function () {
Common.openURL('/contacts/');
},
});
}
if (padType !== 'settings') {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-settings fa fa-cog'},
content: h('span', Messages.settingsButton),
action: function () {
if (padType) {
Common.openURL(origin+'/settings/');
} else {
Common.gotoURL(origin+'/settings/');
}
},
});
}
options.push({ tag: 'hr' });
// Add administration panel link if the user is an admin
if (priv.edPublic && Array.isArray(Config.adminKeys) && Config.adminKeys.indexOf(priv.edPublic) !== -1) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-admin fa fa-cogs'},
content: h('span', Messages.adminPage || 'Admin'),
action: function () {
if (padType) {
Common.openURL(origin+'/admin/');
} else {
Common.gotoURL(origin+'/admin/');
}
},
});
}
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'rel': 'noopener',
'href': 'https://docs.cryptpad.fr',
'class': 'fa fa-book'
},
content: h('span', Messages.docs_link)
});
if (padType !== 'support' && accountName && Config.supportMailbox) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-support fa fa-life-ring'},
content: h('span', Messages.supportPage || 'Support'),
action: function () {
if (padType) {
Common.openURL(origin+'/support/');
} else {
Common.gotoURL(origin+'/support/');
}
},
});
}
options.push({
tag: 'a',
attributes: {
'class': 'cp-toolbar-about fa fa-info',
},
content: h('span', Messages.user_about),
action: function () {
UIElements.displayInfoMenu(Common, metadataMgr);
},
});
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-home'
},
content: h('span', Messages.homePage),
action: function () {
Common.openURL('/index.html');
},
});
// Add the change display name button if not in read only mode
/*
if (config.changeNameButtonCls && config.displayChangeName && !AppConfig.disableProfile) {
options.push({
tag: 'a',
attributes: {'class': config.changeNameButtonCls + ' fa fa-user'},
content: h('span', Messages.user_rename)
});
}*/
options.push({ tag: 'hr' });
// We have code to hide 2 separators in a row, but in the case of survey, they may be
// in the DOM but hidden. We need to know if there are other elements in this
// section to determine if we have to manually hide a separator.
var surveyAlone = true;
if (Config.allowSubscriptions) {
surveyAlone = false;
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-star-o'
},
content: h('span', priv.plan ? Messages.settings_cat_subscription : Messages.pricing),
action: function () {
Common.openURL(priv.plan ? priv.accounts.upgradeURL :'/features.html');
},
});
}
if (!priv.plan && !Config.removeDonateButton) {
surveyAlone = false;
options.push({
tag: 'a',
attributes: {
'class': 'fa fa-gift'
},
content: h('span', Messages.crowdfunding_button2),
action: function () {
Common.openUnsafeURL(priv.accounts.donateURL);
},
});
}
// If you set "" in the admin panel, it will remove the AppConfig survey
var surveyURL = typeof(Broadcast.surveyURL) !== "undefined" ? Broadcast.surveyURL
: AppConfig.surveyURL;
options.push({
tag: 'a',
attributes: {
'class': 'cp-toolbar-survey fa fa-graduation-cap'
},
content: h('span', Messages.survey),
action: function () {
Common.openUnsafeURL(surveyURL);
Feedback.send('SURVEY_CLICKED');
},
});
options.push({ tag: 'hr' });
// Add login or logout button depending on the current status
if (priv.loggedIn) {
options.push({
tag: 'a',
attributes: {
'class': 'cp-toolbar-menu-logout-everywhere fa fa-plug',
},
content: h('span', Messages.logoutEverywhere),
action: function () {
UI.confirm(Messages.settings_logoutEverywhereConfirm, function (yes) {
if (!yes) { return; }
Common.getSframeChannel().query('Q_LOGOUT_EVERYWHERE', null, function () {
Common.gotoURL(origin + '/');
});
});
},
});
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-logout fa fa-sign-out'},
content: h('span', Messages.logoutButton),
action: function () {
Common.logout(function () {
Common.gotoURL(origin+'/');
});
},
});
} else {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-login fa fa-sign-in'},
content: h('span', Messages.login_login),
action: function () {
Common.setLoginRedirect('login');
},
});
if (!Config.restrictRegistration) {
options.push({
tag: 'a',
attributes: {'class': 'cp-toolbar-menu-register fa fa-user-plus'},
content: h('span', Messages.login_register),
action: function () {
Common.setLoginRedirect('register');
},
});
}
}
var $icon = $('', {'class': 'fa fa-user-secret'});
//var $userbig = $('', {'class': 'big'}).append($displayedName.clone());
var $userButton = $('').append($icon);//.append($userbig);
if (accountName) {
$userButton = $('
').append(accountName);
}
/*if (account && config.displayNameCls) {
$userbig.append($('
', {'class': 'account-name'}).text('(' + accountName + ')'));
} else if (account) {
// If no display name, do not display the parentheses
$userbig.append($('', {'class': 'account-name'}).text(accountName));
}*/
var dropdownConfigUser = {
buttonContent: $userButton[0],
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
container: config.$initBlock, // optional
feedback: "USER_ADMIN",
common: Common
};
var $userAdmin = UIElements.createDropdown(dropdownConfigUser);
var $survey = $userAdmin.find('.cp-toolbar-survey');
if (!surveyURL) {
$survey.hide();
if (surveyAlone) { $survey.next('hr').hide(); }
}
Common.makeUniversal('broadcast', {
onEvent: function (obj) {
var cmd = obj.ev;
if (cmd !== "SURVEY") { return; }
var url = obj.data;
if (url === surveyURL) { return; }
if (url && !Util.isValidURL(url)) { return; }
surveyURL = url;
if (!url) {
$survey.hide();
if (surveyAlone) { $survey.next('hr').hide(); }
return;
}
$survey.show();
if (surveyAlone) { $survey.next('hr').show(); }
}
});
/*
// Uncomment these lines to have a language selector in the admin menu
// FIXME clicking on the inner menu hides the outer one
var $lang = UIElements.createLanguageSelector(Common);
$userAdmin.find('.cp-dropdown-content').append($lang);
*/
var $displayName = $userAdmin.find('.'+displayNameCls);
var $avatar = $userAdmin.find('> button .cp-dropdown-button-title');
var loadingAvatar;
var to;
var oldUrl = '';
var oldUid;
var oldName;
var updateButton = function () {
var myData = metadataMgr.getUserData();
var privateData = metadataMgr.getPrivateData();
var uid = myData.uid;
if (!priv.plan && privateData.plan) {
config.$initBlock.empty();
metadataMgr.off('change', updateButton);
UIElements.createUserAdminMenu(Common, config);
return;
}
if (!myData) { return; }
if (loadingAvatar) {
// Try again in 200ms
window.clearTimeout(to);
to = window.setTimeout(updateButton, 200);
return;
}
loadingAvatar = true;
var newName = UI.getDisplayName(myData.name);
var url = myData.avatar;
$displayName.text(newName);
if ((accountName && oldUrl !== url) || !accountName && uid !== oldUid || oldName !== newName) {
$avatar.html('');
Common.displayAvatar($avatar, url, newName, function ($img) {
oldUrl = url;
oldUid = uid;
oldName = newName;
$userAdmin.find('> button').removeClass('cp-avatar');
if ($img) { $userAdmin.find('> button').addClass('cp-avatar'); }
loadingAvatar = false;
}, uid);
return;
}
loadingAvatar = false;
};
metadataMgr.onChange(updateButton);
updateButton();
return $userAdmin;
};
// Provide $container if you want to put the generated block in another element
// Provide $initBlock if you already have the menu block and you want the content inserted in it
UIElements.createLanguageSelector = function (common, $container, $initBlock) {
var options = [];
var languages = Messages._languages;
var keys = Object.keys(languages).sort();
keys.forEach(function (l) {
options.push({
tag: 'a',
attributes: {
'class': 'cp-language-value',
'data-value': l,
'href': '#',
},
content: [ // supplying content as an array ensures it's a text node, not parsed HTML
languages[l] // Pretty name of the language value
],
});
});
var dropdownConfig = {
text: Messages.language, // Button initial text
options: options, // Entries displayed in the menu
//left: true, // Open to the left of the button
container: $initBlock, // optional
isSelect: true,
common: common
};
var $block = UIElements.createDropdown(dropdownConfig);
$block.attr('id', 'cp-language-selector');
if ($container) {
$block.appendTo($container);
}
Language.initSelector($block, common);
return $block;
};
UIElements.createNewPadModal = function (common) {
// if in drive, show new pad modal instead
if ($(".cp-app-drive-element-row.cp-app-drive-new-ghost").length !== 0) {
return void $(".cp-app-drive-element-row.cp-app-drive-new-ghost").click();
}
var modal = UI.createModal({
id: 'cp-app-toolbar-creation-dialog',
$body: $('body')
});
var $modal = modal.$modal;
var $title = $(h('h3', [ h('i.fa.fa-plus'), ' ', Messages.fm_newButton ]));
var $description = $('').html(Messages.creation_newPadModalDescription);
$modal.find('.cp-modal').append($title);
$modal.find('.cp-modal').append($description);
var $container = $('
');
var i = 0;
var types = AppConfig.availablePadTypes.filter(function (p) {
if (AppConfig.hiddenTypes.indexOf(p) !== -1) { return; }
if (!common.isLoggedIn() && AppConfig.registeredOnlyTypes &&
AppConfig.registeredOnlyTypes.indexOf(p) !== -1) { return; }
return true;
});
types.forEach(function (p) {
var $element = $('
', {
'class': 'cp-icons-element',
'id': 'cp-newpad-icons-'+ (i++)
}).prepend(UI.getIcon(p)).appendTo($container);
$element.append($('', {'class': 'cp-icons-name'})
.text(Messages.type[p]));
$element.attr('data-type', p);
$element.click(function () {
$modal.hide();
common.openURL('/' + p + '/');
});
var premium = common.checkRestrictedApp(p);
if (premium < 0) {
$element.addClass('cp-app-hidden cp-app-disabled');
} else if (premium === 0) {
$element.addClass('cp-app-disabled');
}
});
var selected = -1;
var next = function () {
selected = ++selected % types.length;
$container.find('.cp-icons-element-selected').removeClass('cp-icons-element-selected');
$container.find('#cp-newpad-icons-'+selected).addClass('cp-icons-element-selected');
};
$modal.off('keydown');
$modal.keydown(function (e) {
if (e.which === 9) {
e.preventDefault();
e.stopPropagation();
next();
return;
}
if (e.which === 13) {
if ($container.find('.cp-icons-element-selected').length === 1) {
$container.find('.cp-icons-element-selected').click();
}
return;
}
});
$modal.find('.cp-modal').append($container);
window.setTimeout(function () {
modal.show();
$modal.focus();
});
};
UIElements.openFilePicker = function (common, types, cb) {
var sframeChan = common.getSframeChannel();
sframeChan.query("Q_FILE_PICKER_OPEN", types, function (err, data) {
if (err) { return; }
cb(data);
});
};
UIElements.openTemplatePicker = function (common, force) {
var metadataMgr = common.getMetadataMgr();
var type = metadataMgr.getMetadataLazy().type;
var sframeChan = common.getSframeChannel();
var focus;
var pickerCfgInit = {
types: [type],
where: ['template'],
hidden: true
};
var pickerCfg = {
types: [type],
where: ['template'],
};
var onConfirm = function (yes) {
if (!yes) {
if (focus) { focus.focus(); }
return;
}
delete pickerCfg.hidden;
var first = true; // We can only pick a template once (for a new document)
common.openFilePicker(pickerCfg, function (data) {
if (data.type === type && first) {
UI.addLoadingScreen({hideTips: true});
var chatChan = common.getPadChat();
var cursorChan = common.getCursorChannel();
sframeChan.query('Q_TEMPLATE_USE', {
href: data.href,
chat: chatChan,
cursor: cursorChan
}, function () {
first = false;
UI.removeLoadingScreen();
Feedback.send('TEMPLATE_USED');
});
if (focus) { focus.focus(); }
return;
}
});
};
sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) {
if (data) {
common.openFilePicker(pickerCfgInit);
focus = document.activeElement;
if (force) { return void onConfirm(true); }
UI.confirm(Messages.useTemplate, onConfirm, {
ok: Messages.useTemplateOK,
cancel: Messages.useTemplateCancel,
});
} else if (force) {
UI.alert(Messages.template_empty);
}
});
};
/*
UIElements.setExpirationValue = function (val, $expire) {
if (val && typeof (val) === "number") {
$expire.find('#cp-creation-expire').attr('checked', true).trigger('change');
$expire.find('#cp-creation-expire-true').attr('checked', true);
if (val % (3600 * 24 * 30) === 0) {
$expire.find('#cp-creation-expire-unit').val("month");
$expire.find('#cp-creation-expire-val').val(val / (3600 * 24 * 30));
return;
}
if (val % (3600 * 24) === 0) {
$expire.find('#cp-creation-expire-unit').val("day");
$expire.find('#cp-creation-expire-val').val(val / (3600 * 24));
return;
}
if (val % 3600 === 0) {
$expire.find('#cp-creation-expire-unit').val("hour");
$expire.find('#cp-creation-expire-val').val(val / 3600);
return;
}
// if we're here, it means we don't have a valid value so we should check unlimited
$expire.find('#cp-creation-expire-false').attr('checked', true);
}
};
*/
UIElements.getPadCreationScreen = function (common, cfg, appCfg, cb) {
appCfg = appCfg || {};
if (!common.isLoggedIn()) { return void cb(); }
var sframeChan = common.getSframeChannel();
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
if (privateData.offline) {
var onChange = function () {
var privateData = metadataMgr.getPrivateData();
if (privateData.offline) { return; }
UIElements.getPadCreationScreen(common, cfg, appCfg, cb);
metadataMgr.off('change', onChange);
};
metadataMgr.onChange(onChange);
return;
}
var type = metadataMgr.getMetadataLazy().type || privateData.app;
var fromFileData = privateData.fromFileData;
var fromContent = privateData.fromContent;
var $body = $('body');
var $creationContainer = $('', { id: 'cp-creation-container' }).appendTo($body);
var urlArgs = (Config.requireConf && Config.requireConf.urlArgs) || '';
var logo = h('img', { src: '/customize/CryptPad_logo.svg?' + urlArgs });
var fill1 = h('div.cp-creation-fill.cp-creation-logo', logo);
var fill2 = h('div.cp-creation-fill');
var $creation = $('
', { id: 'cp-creation', tabindex:1 });
$creationContainer.append([fill1, $creation, fill2]);
var createHelper = function (href, text) {
var q = UI.createHelper(href, text);
$(q).addClass('cp-creation-help');
return q;
};
// Title
//$creation.append(h('h2.cp-creation-title', Messages.newButtonTitle));
var newPadH3Title = Messages._getKey('creation_new',[Messages.type[type]]);
var early = common.checkRestrictedApp(type);
var domain = Config.httpUnsafeOrigin || 'CryptPad';
if (/^http/.test(domain)) { domain = domain.replace(/^https?\:\/\//, ''); }
var title = h('div.cp-creation-title', [
UI.getFileIcon({type: type})[0],
h('div.cp-creation-title-text', [
h('span', newPadH3Title),
createHelper(Pages.localizeDocsLink('https://docs.cryptpad.fr/en/user_guide/apps/general.html#new-document'), Messages.creation_helperText)
])
]);
$creation.append(title);
if (early === 1) {
$creation.append(h('div.cp-creation-early.alert.alert-warning', Messages._getKey('premiumAccess', [
domain
])));
}
//var colorClass = 'cp-icon-color-'+type;
//$creation.append(h('h2.cp-creation-title.'+colorClass, Messages.newButtonTitle));
// Deleted pad warning
if (metadataMgr.getPrivateData().isDeleted) {
$creation.append(h('div.cp-creation-deleted-container',
h('div.cp-creation-deleted', Messages.creation_404)
));
}
// Team pad
var team;
// FIXME: broken wen cache is enabled
var teamExists = privateData.teams && Object.keys(privateData.teams).length;
var teamValue;
// storeInTeam can be
// * a team ID ==> store in the team drive, and the team will be the owner
// * -1 ==> store in the user drive, and the user will be the owner
// * undefined ==> ask
if (teamExists) {
var teams = Object.keys(privateData.teams).map(function (id) {
var data = privateData.teams[id];
var avatar = h('span.cp-creation-team-avatar.cp-avatar');
// We assume that teams always have a non-empty name, so we don't need a UID
common.displayAvatar($(avatar), data.avatar, data.name);
return h('div.cp-creation-team', {
'data-id': id,
title: data.name,
},[
avatar,
h('span.cp-creation-team-name', data.name)
]);
});
teams.unshift(h('div.cp-creation-team', {
'data-id': '-1',
title: Messages.settings_cat_drive
}, [
h('span.cp-creation-team-avatar.fa.fa-hdd-o'),
h('span.cp-creation-team-name', Messages.settings_cat_drive)
]));
team = h('div.cp-creation-teams', [
Messages.team_pcsSelectLabel,
h('div.cp-creation-teams-grid', teams),
createHelper('#', Messages.team_pcsSelectHelp)
]);
var $team = $(team);
$team.find('.cp-creation-team').click(function () {
if ($(this).hasClass('cp-selected')) {
teamValue = undefined;
return void $(this).removeClass('cp-selected');
}
$team.find('.cp-creation-team').removeClass('cp-selected');
$(this).addClass('cp-selected');
teamValue = $(this).attr('data-id');
});
if (privateData.storeInTeam) {
$team.find('[data-id="'+privateData.storeInTeam+'"]').addClass('cp-selected');
teamValue = privateData.storeInTeam;
}
}
// Owned pads
// Default is Owned pad
var owned = h('div.cp-creation-owned', [
UI.createCheckbox('cp-creation-owned', Messages.creation_owned, true),
]);
// Life time
var expire = h('div.cp-creation-expire', [
UI.createCheckbox('cp-creation-expire', Messages.creation_expiration, false, {
labelAlt: Messages.creation_expiresIn
}),
h('span.cp-creation-expire-picker.cp-creation-slider', [
h('input#cp-creation-expire-val', {
type: "number",
min: 1,
max: 100,
value: 3
}),
h('select#cp-creation-expire-unit', [
h('option', { value: 'hour' }, Messages.creation_expireHours),
h('option', { value: 'day' }, Messages.creation_expireDays),
h('option', {
value: 'month',
selected: 'selected'
}, Messages.creation_expireMonths)
])
]),
]);
// Password
var password = h('div.cp-creation-password', [
UI.createCheckbox('cp-creation-password', Messages.properties_addPassword, false),
h('span.cp-creation-password-picker.cp-creation-slider', [
UI.passwordInput({id: 'cp-creation-password-val'})
/*h('input#cp-creation-password-val', {
type: "text" // TODO type password with click to show
}),*/
]),
//createHelper('#', "TODO: password protection adds another layer of security ........") // TODO
]);
var $w = $(window);
var big = $w.width() > 800;
var right = h('span.fa.fa-chevron-right.cp-creation-template-more');
var left = h('span.fa.fa-chevron-left.cp-creation-template-more');
if (!big) {
$(left).removeClass('fa-chevron-left').addClass('fa-chevron-up');
$(right).removeClass('fa-chevron-right').addClass('fa-chevron-down');
}
var templates = h('div.cp-creation-template', [
left,
h('div.cp-creation-template-container', [
h('span.fa.fa-circle-o-notch.fa-spin.fa-4x.fa-fw')
]),
right
]);
var createDiv = h('div.cp-creation-create');
var $create = $(createDiv);
$(h('div#cp-creation-form', [
h('div.cp-creation-checkboxes', [
team,
owned,
expire,
password,
]),
templates,
createDiv
])).appendTo($creation);
// Display templates
var selected = 0; // Selected template in the list (highlighted)
var TEMPLATES_DISPLAYED = big ? 6 : 3; // Max templates displayed per page
var next = function () {}; // Function called when pressing tab to highlight the next template
var i = 0; // Index of the first template displayed in the current page
sframeChan.query("Q_CREATE_TEMPLATES", type, function (err, res) {
if (!res.data || !Array.isArray(res.data)) {
return void console.error("Error: get the templates list");
}
var allData = res.data.slice().sort(function (a, b) {
if (a.used === b.used) {
// Sort by name
if (a.name === b.name) { return 0; }
return a.name < b.name ? -1 : 1;
}
return b.used - a.used;
});
/*if (!appCfg.noTemplates) {
allData.unshift({
name: Messages.creation_newTemplate,
id: -1,
//icon: h('span.fa.fa-bookmark')
icon: h('span.cptools.cptools-new-template')
});
}*/
if (!privateData.newTemplate) {
allData.unshift({
name: Messages.creation_noTemplate,
id: 0,
//icon: h('span.fa.fa-file')
icon: UI.getFileIcon({type: type})
});
}
var redraw = function (index) {
if (index < 0) { i = 0; }
else if (index > allData.length - 1) { return; }
else { i = index; }
var data = allData.slice(i, i + TEMPLATES_DISPLAYED);
var $container = $(templates).find('.cp-creation-template-container').html('');
data.forEach(function (obj, idx) {
var name = obj.name;
var $span = $('', {
'class': 'cp-creation-template-element',
'title': name,
}).appendTo($container);
$span.data('id', obj.id);
if (obj.content) { $span.data('content', obj.content); }
if (idx === selected) { $span.addClass('cp-creation-template-selected'); }
if (!obj.thumbnail) {
$span.append(obj.icon || h('span.cptools.cptools-template'));
}
$('', {'class': 'cp-creation-template-element-name'}).text(name)
.appendTo($span);
$span.click(function () {
$container.find('.cp-creation-template-selected')
.removeClass('cp-creation-template-selected');
$span.addClass('cp-creation-template-selected');
selected = idx;
});
// Add thumbnail if it exists
if (obj.thumbnail) {
common.addThumbnail(obj.thumbnail, $span, function () {});
}
});
$(right).off('click').removeClass('hidden').click(function () {
selected = 0;
redraw(i + TEMPLATES_DISPLAYED);
});
if (i >= allData.length - TEMPLATES_DISPLAYED ) { $(right).addClass('hidden'); }
$(left).off('click').removeClass('hidden').click(function () {
selected = TEMPLATES_DISPLAYED - 1;
redraw(i - TEMPLATES_DISPLAYED);
});
if (i < TEMPLATES_DISPLAYED) { $(left).addClass('hidden'); }
};
if (fromFileData) {
var todo = function (thumbnail) {
allData = [{
name: fromFileData.title,
id: 0,
thumbnail: thumbnail,
icon: h('span.cptools.cptools-file'),
}];
redraw(0);
};
todo();
sframeChan.query("Q_GET_FILE_THUMBNAIL", null, function (err, res) {
if (err || (res && res.error)) { return; }
todo(res.data);
});
}
else if (fromContent) {
allData = [{
name: fromContent.title,
id: 0,
icon: h('span.cptools.cptools-poll'),
}];
redraw(0);
}
else {
redraw(0);
}
// Change template selection when Tab is pressed
next = function (revert) {
var max = $creation.find('.cp-creation-template-element').length;
if (selected + 1 === max && !revert) {
selected = i + TEMPLATES_DISPLAYED < allData.length ? 0 : max;
return void redraw(i + TEMPLATES_DISPLAYED);
}
if (selected === 0 && revert) {
selected = i - TEMPLATES_DISPLAYED >= 0 ? TEMPLATES_DISPLAYED - 1 : 0;
return void redraw(i - TEMPLATES_DISPLAYED);
}
selected = revert ?
(--selected < 0 ? 0 : selected) :
++selected >= max ? max-1 : selected;
$creation.find('.cp-creation-template-element')
.removeClass('cp-creation-template-selected');
$($creation.find('.cp-creation-template-element').get(selected))
.addClass('cp-creation-template-selected');
};
$w.on('resize', function () {
var _big = $w.width() > 800;
if (big === _big) { return; }
big = _big;
if (!big) {
$(left).removeClass('fa-chevron-left').addClass('fa-chevron-up');
$(right).removeClass('fa-chevron-right').addClass('fa-chevron-down');
} else {
$(left).removeClass('fa-chevron-up').addClass('fa-chevron-left');
$(right).removeClass('fa-chevron-down').addClass('fa-chevron-right');
}
TEMPLATES_DISPLAYED = big ? 6 : 3;
redraw(0);
});
});
// Display expiration form when checkbox checked
$creation.find('#cp-creation-expire').on('change', function () {
if ($(this).is(':checked')) {
$creation.find('.cp-creation-expire-picker:not(.active)').addClass('active');
$creation.find('.cp-creation-expire:not(.active)').addClass('active');
$creation.find('#cp-creation-expire-val').focus();
return;
}
$creation.find('.cp-creation-expire-picker').removeClass('active');
$creation.find('.cp-creation-expire').removeClass('active');
$creation.focus();
});
// Display password form when checkbox checked
$creation.find('#cp-creation-password').on('change', function () {
if ($(this).is(':checked')) {
$creation.find('.cp-creation-password-picker:not(.active)').addClass('active');
$creation.find('.cp-creation-password:not(.active)').addClass('active');
$creation.find('#cp-creation-password-val').focus();
return;
}
$creation.find('.cp-creation-password-picker').removeClass('active');
$creation.find('.cp-creation-password').removeClass('active');
$creation.focus();
});
// Keyboard shortcuts
$creation.find('#cp-creation-expire-val').keydown(function (e) {
if (e.which === 9) {
e.stopPropagation();
}
});
$creation.find('#cp-creation-expire-unit').keydown(function (e) {
if (e.which === 9 && e.shiftKey) {
e.stopPropagation();
}
});
// Initial values
/*
if (!cfg.owned && typeof cfg.owned !== "undefined") {
$creation.find('#cp-creation-owned').prop('checked', false);
}
UIElements.setExpirationValue(cfg.expire, $creation);
*/
// Create the pad
var getFormValues = function () {
// Type of pad
var ownedVal = $('#cp-creation-owned').is(':checked') ? 1 : 0;
// Life time
var expireVal = 0;
if($('#cp-creation-expire').is(':checked')) {
var unit = 0;
switch ($('#cp-creation-expire-unit').val()) {
case "hour" : unit = 3600; break;
case "day" : unit = 3600 * 24; break;
case "month": unit = 3600 * 24 * 30; break;
default: unit = 0;
}
expireVal = ($('#cp-creation-expire-val').val() || 0) * unit;
}
// Password
var passwordVal = $('#cp-creation-password').is(':checked') ?
$('#cp-creation-password-val').val() : undefined;
var $template = $creation.find('.cp-creation-template-selected');
var templateId = $template.data('id') || undefined;
var templateContent = $template.data('content') || undefined;
// Team
var team;
if (teamValue) {
team = privateData.teams[teamValue] || {};
team.id = Number(teamValue);
}
return {
owned: ownedVal,
password: passwordVal,
expire: expireVal,
templateId: templateId,
templateContent: templateContent,
team: team
};
};
var create = function () {
var val = getFormValues();
common.setAttribute(['general', 'creation', 'owned'], val.owned, function (e) {
if (e) { return void console.error(e); }
});
common.setAttribute(['general', 'creation', 'expire'], val.expire, function (e) {
if (e) { return void console.error(e); }
});
if (val.expire) {
Feedback.send('EXPIRING_PAD-'+val.expire);
}
$creationContainer.remove();
common.createPad(val, function () {
cb();
});
};
var $button = $('