Merge branch 'pcs' into staging

This commit is contained in:
yflory
2018-04-19 11:14:56 +02:00
40 changed files with 810 additions and 448 deletions

View File

@@ -6,13 +6,13 @@ define([
'/common/common-notifier.js',
'/customize/application_config.js',
'/bower_components/alertifyjs/dist/js/alertify.js',
'/common/tippy.min.js',
'/common/tippy/tippy.min.js',
'/customize/pages.js',
'/common/hyperscript.js',
'/common/test.js',
'/bower_components/bootstrap-tokenfield/dist/bootstrap-tokenfield.js',
'css!/common/tippy.css',
'css!/common/tippy/tippy.css',
], function ($, Messages, Util, Hash, Notifier, AppConfig,
Alertify, Tippy, Pages, h, Test) {
var UI = {};
@@ -539,16 +539,16 @@ define([
var LOADING = 'cp-loading';
var getRandomTip = function () {
/*var getRandomTip = function () {
if (!Messages.tips || !Object.keys(Messages.tips).length) { return ''; }
var keys = Object.keys(Messages.tips);
var rdm = Math.floor(Math.random() * keys.length);
return Messages.tips[keys[rdm]];
};
};*/
UI.addLoadingScreen = function (config) {
config = config || {};
var loadingText = config.loadingText;
var hideTips = config.hideTips || AppConfig.hideLoadingScreenTips;
//var hideTips = config.hideTips || AppConfig.hideLoadingScreenTips;
var hideLogo = config.hideLogo;
var $loading, $container;
if ($('#' + LOADING).length) {
@@ -557,9 +557,9 @@ define([
$loading.removeClass('cp-loading-hidden');
$('.cp-loading-spinner-container').show();
if (loadingText) {
$('#' + LOADING).find('p').text(loadingText);
$('#' + LOADING).find('p').show().text(loadingText);
} else {
$('#' + LOADING).find('p').text('');
$('#' + LOADING).find('p').hide().text('');
}
$container = $loading.find('.cp-loading-container');
} else {
@@ -574,14 +574,14 @@ define([
$spinner.show();
$('body').append($loading);
}
if (Messages.tips && !hideTips) {
/*if (Messages.tips && !hideTips) {
var $loadingTip = $('<div>', {'id': 'cp-loading-tip'});
$('<span>', {'class': 'tips'}).text(getRandomTip()).appendTo($loadingTip);
$loadingTip.css({
'bottom': $('body').height()/2 - $container.height()/2 + 20 + 'px'
});
$('body').append($loadingTip);
}
}*/
};
UI.removeLoadingScreen = function (cb) {
// Release the test blocker, hopefully every test has been registered.
@@ -610,8 +610,8 @@ define([
}
$('.cp-loading-spinner-container').hide();
$('#cp-loading-tip').remove();
if (transparent) { $('#' + LOADING).css('opacity', 0.8); }
$('#' + LOADING).find('p').html(error || Messages.error);
if (transparent) { $('#' + LOADING).css('opacity', 0.9); }
$('#' + LOADING).find('p').show().html(error || Messages.error);
if (exitable) {
$(window).focus();
$(window).keydown(function (e) {
@@ -660,18 +660,38 @@ define([
});
};
var delay = typeof(AppConfig.tooltipDelay) === "number" ? AppConfig.tooltipDelay : 500;
$.extend(true, Tippy.defaults, {
placement: 'bottom',
performance: true,
delay: [delay, 0],
//sticky: true,
theme: 'cryptpad',
arrow: true,
maxWidth: '200px',
flip: true,
popperOptions: {
modifiers: {
preventOverflow: { boundariesElement: 'window' }
}
},
//arrowType: 'round',
arrowTransform: 'scale(2)',
zIndex: 100000001
});
UI.addTooltips = function () {
var MutationObserver = window.MutationObserver;
var delay = typeof(AppConfig.tooltipDelay) === "number" ? AppConfig.tooltipDelay : 500;
var addTippy = function (i, el) {
if (el.nodeName === 'IFRAME') { return; }
Tippy(el, {
position: 'bottom',
distance: 0,
performance: true,
delay: [delay, 0],
sticky: true
var opts = {
distance: 15
};
Array.prototype.slice.apply(el.attributes).filter(function (obj) {
return /^data-tippy-/.test(obj.name);
}).forEach(function (obj) {
opts[obj.name.slice(11)] = obj.value;
});
Tippy(el, opts);
};
// This is the robust solution to remove dangling tooltips
// The mutation observer does not always find removed nodes.
@@ -720,5 +740,9 @@ define([
});
};
UI.createCheckbox = Pages.createCheckbox;
UI.createRadio = Pages.createRadio;
return UI;
});

View File

@@ -13,8 +13,6 @@ define([
'/customize/messages.js',
'/customize/application_config.js',
'/bower_components/nthen/index.js',
'css!/common/tippy.css',
], function ($, Config, Util, Hash, Language, UI, Constants, Feedback, h, MediaTag, Clipboard,
Messages, AppConfig, NThen) {
var UIElements = {};
@@ -237,7 +235,11 @@ define([
var link = h('div.cp-share-modal', [
h('label', Messages.share_linkAccess),
h('br'),
h('input#cp-share-editable-true.cp-share-editable-value', {
UI.createRadio('cp-share-editable', 'cp-share-editable-true',
Messages.share_linkEdit, true, { mark: {tabindex:1} }),
UI.createRadio('cp-share-editable', 'cp-share-editable-false',
Messages.share_linkView, false, { mark: {tabindex:1} }),
/*h('input#cp-share-editable-true.cp-share-editable-value', {
type: 'radio',
name: 'cp-share-editable',
value: 1,
@@ -248,25 +250,14 @@ define([
name: 'cp-share-editable',
value: 0
}),
h('label', { 'for': 'cp-share-editable-false' }, Messages.share_linkView),
h('br'),
h('label', { 'for': 'cp-share-editable-false' }, Messages.share_linkView),*/
h('br'),
h('label', Messages.share_linkOptions),
h('br'),
h('input#cp-share-embed', {
type: 'checkbox',
name: 'cp-share-embed'
}),
h('label', { 'for': 'cp-share-embed' }, Messages.share_linkEmbed),
UI.createCheckbox('cp-share-embed', Messages.share_linkEmbed, false, { mark: {tabindex:1} }),
UI.createCheckbox('cp-share-present', Messages.share_linkPresent, false, { mark: {tabindex:1} }),
h('br'),
h('input#cp-share-present', {
type: 'checkbox',
name: 'cp-share-present'
}),
h('label', { 'for': 'cp-share-present' }, Messages.share_linkPresent),
h('br'),
h('br'),
UI.dialog.selectable('', { id: 'cp-share-link-preview' })
UI.dialog.selectable('', { id: 'cp-share-link-preview', tabindex: 1 })
]);
if (!hashes.editHash) {
$(link).find('#cp-share-editable-false').attr('checked', true);
@@ -1685,14 +1676,10 @@ define([
var priv = common.getMetadataMgr().getPrivateData();
var c = (priv.settings.general && priv.settings.general.creation) || {};
if (AppConfig.displayCreationScreen && common.isLoggedIn() && c.skip) {
$advanced = $('<input>', {
type: 'checkbox',
checked: 'checked',
id: 'cp-app-toolbar-creation-advanced'
}).appendTo($advancedContainer);
$('<label>', {
for: 'cp-app-toolbar-creation-advanced'
}).text(Messages.creation_newPadModalAdvanced).appendTo($advancedContainer);
var $cboxLabel = $(UI.createCheckbox('cp-app-toolbar-creation-advanced',
Messages.creation_newPadModalAdvanced, true))
.appendTo($advancedContainer);
$advanced = $cboxLabel.find('input');
$description.append('<br>');
$description.append(Messages.creation_newPadModalDescriptionAdvanced);
}
@@ -1782,11 +1769,15 @@ define([
var sframeChan = common.getSframeChannel();
var focus;
var pickerCfg = {
var pickerCfgInit = {
types: [type],
where: ['template'],
hidden: true
};
var pickerCfg = {
types: [type],
where: ['template'],
};
var onConfirm = function (yes) {
if (!yes) {
if (focus) { focus.focus(); }
@@ -1814,7 +1805,7 @@ define([
sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) {
if (data) {
common.openFilePicker(pickerCfg);
common.openFilePicker(pickerCfgInit);
focus = document.activeElement;
if (force) { return void onConfirm(true); }
UI.confirm(Messages.useTemplate, onConfirm, {
@@ -1858,11 +1849,15 @@ define([
var $body = $('body');
var $creationContainer = $('<div>', { id: 'cp-creation-container' }).appendTo($body);
var urlArgs = (Config.requireConf && Config.requireConf.urlArgs) || '';
var l = h('div.cp-creation-logo', h('img', { src: '/customize/alt-favicon.png?' + urlArgs }));
$(l).appendTo($creationContainer);
var $creation = $('<div>', { id: 'cp-creation', tabindex: 1 }).appendTo($creationContainer);
// Title
var colorClass = 'cp-icon-color-'+type;
$creation.append(h('h2.cp-creation-title', Messages.newButtonTitle));
//var colorClass = 'cp-icon-color-'+type;
//$creation.append(h('h2.cp-creation-title', Messages.newButtonTitle));
$creation.append(h('h3.cp-creation-title', Messages['button_new'+type]));
//$creation.append(h('h2.cp-creation-title.'+colorClass, Messages.newButtonTitle));
// Deleted pad warning
@@ -1874,10 +1869,11 @@ define([
var origin = common.getMetadataMgr().getPrivateData().origin;
var createHelper = function (href, text) {
var q = h('a.cp-creation-help.fa.fa-question', {
var q = h('a.cp-creation-help.fa.fa-question-circle', {
title: text,
href: origin + href,
target: "_blank"
target: "_blank",
'data-tippy-placement': "right"
});
return q;
};
@@ -1885,30 +1881,14 @@ define([
// Owned pads
// Default is Owned pad
var owned = h('div.cp-creation-owned', [
h('label.cp-checkmark', [
h('input', {
type: 'checkbox',
id: 'cp-creation-owned',
checked: 'checked'
}),
h('span.cp-checkmark-mark'),
Messages.creation_owned
]),
UI.createCheckbox('cp-creation-owned', Messages.creation_owned, true),
createHelper('/faq.html#keywords-owned', Messages.creation_owned1)
]);
// Life time
var expire = h('div.cp-creation-expire', [
h('label.cp-checkmark', [
h('input', {
type: 'checkbox',
id: 'cp-creation-expire'
}),
h('span.cp-checkmark-mark'),
Messages.creation_expire
]),
createHelper('/faq.html#keywords-expiring', Messages.creation_expire2),
h('div.cp-creation-expire-picker.cp-creation-slider', [
UI.createCheckbox('cp-creation-expire', Messages.creation_expire, false),
h('span.cp-creation-expire-picker.cp-creation-slider', [
h('input#cp-creation-expire-val', {
type: "number",
min: 1,
@@ -1923,106 +1903,142 @@ define([
selected: 'selected'
}, Messages.creation_expireMonths)
])
]),
createHelper('/faq.html#keywords-expiring', Messages.creation_expire2),
]);
var right = h('span.fa.fa-chevron-right.cp-creation-template-more');
var left = h('span.fa.fa-chevron-left.cp-creation-template-more');
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 settings = h('div.cp-creation-remember', [
UI.createCheckbox('cp-creation-remember', Messages.creation_saveSettings, false),
createHelper('/settings/#creation', Messages.creation_settings),
h('div.cp-creation-remember-help.cp-creation-slider', [
h('span.fa.fa-exclamation-circle.cp-creation-warning'),
Messages.creation_rememberHelp
])
]);
var createDiv = h('div.cp-creation-create');
var $create = $(createDiv);
var templates = h('div.cp-creation-template', [
h('h3.cp-creation-title.'+colorClass, Messages['button_new'+type]),
h('div.cp-creation-template-container', [
h('span.fa.fa-circle-o-notch.fa-spin.fa-4x.fa-fw')
]),
createDiv
]);
var settings = h('div.cp-creation-remember', [
h('label.cp-checkmark', [
h('input', {
type: 'checkbox',
id: 'cp-creation-remember'
}),
h('span.cp-checkmark-mark'),
Messages.creation_saveSettings
]),
createHelper('/settings/#creation', Messages.creation_settings),
h('div.cp-creation-remember-help.cp-creation-slider', Messages.creation_rememberHelp)
]);
$(h('div#cp-creation-form', [
owned,
expire,
settings,
templates
templates,
createDiv
])).appendTo($creation);
// Display templates
var selected = 0;
var selected = 0; // Selected template in the list (highlighted)
var TEMPLATES_DISPLAYED = 4; // 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 data = res.data.slice().sort(function (a, b) {
if (a.name === b.name) { return 0; }
return a.name < b.name ? -1 : 1;
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;
});
data.unshift({
name: Messages.creation_noTemplate,
id: 0,
icon: h('span.fa.fa-file')
});
data.push({
allData.unshift({
name: Messages.creation_newTemplate,
id: -1,
icon: h('span.fa.fa-bookmark')
});
var $container = $(templates).find('.cp-creation-template-container').html('');
data.forEach(function (obj, idx) {
var name = obj.name;
var $span = $('<span>', {
'class': 'cp-creation-template-element',
'title': name,
}).appendTo($container);
$span.data('id', obj.id);
if (idx === 0) { $span.addClass('cp-creation-template-selected'); }
$span.append(obj.icon || UI.getFileIcon({type: type}));
$('<span>', {'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 () {});
}
allData.unshift({
name: Messages.creation_noTemplate,
id: 0,
icon: h('span.fa.fa-file')
});
});
// Change template selection when Tab is pressed
var next = function (revert) {
var max = $creation.find('.cp-creation-template-element').length;
selected = revert ?
(--selected < 0 ? max-1 : selected) :
++selected % max;
$creation.find('.cp-creation-template-element')
.removeClass('cp-creation-template-selected');
$($creation.find('.cp-creation-template-element').get(selected))
.addClass('cp-creation-template-selected');
};
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 = $('<span>', {
'class': 'cp-creation-template-element',
'title': name,
}).appendTo($container);
$span.data('id', obj.id);
if (idx === selected) { $span.addClass('cp-creation-template-selected'); }
$span.append(obj.icon || UI.getFileIcon({type: type}));
$('<span>', {'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'); }
};
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');
};
});
// 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();
});

View File

@@ -424,6 +424,7 @@ define([
// it allows us to add owners and expiration time if it is a new file
var parsed = Hash.parsePadUrl(href);
if(!parsed) { throw new Error("Cannot get template hash"); }
postMessage("INCREMENT_TEMPLATE_USE", href);
Crypt.get(parsed.hash, function (err, val) {
if (err) { throw new Error(err); }
var p = Hash.parsePadUrl(window.location.href);

View File

@@ -1,3 +1,5 @@
// dark #326599
// light #4591c4
define([], function () {
var loadingStyle = (function(){/*
#cp-loading {
@@ -9,31 +11,74 @@ define([], function () {
bottom: 0px;
left: 0px;
right: 0px;
background: #222;
background: linear-gradient(to right, #326599 0%, #326599 50%, #4591c4 50%, #4591c4 100%);
color: #fafafa;
text-align: center;
font-size: 1.5em;
opacity: 1;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
}
#cp-loading.cp-loading-hidden {
opacity: 0;
visibility: hidden;
}
#cp-loading .cp-loading-logo {
height: 300px;
width: 300px;
margin-top: 50px;
flex: 0 1 auto;
min-height: 0;
text-align: center;
}
#cp-loading .cp-loading-logo img {
max-width: 100%;
max-height: 100%;
}
#cp-loading .cp-loading-container {
margin-top: 50vh;
transform: translateY(-50%);
width: 700px;
max-width: 90vw;
height: 500px;
max-height: calc(100vh - 20px);
margin: 50px;
flex-shrink: 0;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
}
@media screen and (max-height: 800px) {
#cp-loading .cp-loading-container {
height: auto;
}
}
@media screen and (max-width: 600px) {
#cp-loading .cp-loading-container {
height: auto;
}
}
#cp-loading .cp-loading-cryptofist {
margin-left: auto;
margin-right: auto;
height: 300px;
//height: 300px;
max-width: 90vw;
max-height: 300px;
width: auto;
height: auto;
margin-bottom: 2em;
}
@media screen and (max-height: 450px) {
#cp-loading .cp-loading-cryptofist {
display: none;
}
}
#cp-loading-message {
background: #FFF;
padding: 20px;
width: 100%;
color: #000;
display: none;
}
#cp-loading .cp-loading-spinner-container {
position: relative;
height: 100px;
@@ -75,8 +120,10 @@ define([], function () {
'<style>',
loadingStyle,
'</style>',
'<div class="cp-loading-logo">',
'<img class="cp-loading-cryptofist" src="/customize/alt-favicon.png?' + urlArgs + '">',
'</div>',
'<div class="cp-loading-container">',
'<img class="cp-loading-cryptofist" src="/customize/cryptpad-new-logo-colors-logoonly.png?' + urlArgs + '">',
'<div class="cp-loading-spinner-container">',
'<span class="fa fa-circle-o-notch fa-spin fa-4x fa-fw"></span>',
'</div>',

View File

@@ -660,6 +660,15 @@ define([
});
cb(res);
};
Store.incrementTemplateUse = function (href) {
store.userObject.getPadAttribute(href, 'used', function (err, data) {
// This is a not critical function, abort in case of error to make sure we won't
// create any issue with the user object or the async store
if (err) { return; }
var used = typeof data === "number" ? ++data : 1;
store.userObject.setPadAttribute(href, 'used', used);
});
};
// Pads
Store.moveToTrash = function (data, cb) {

View File

@@ -126,6 +126,9 @@ define([
case 'GET_STRONGER_HASH': {
Store.getStrongerHash(data, cb); break;
}
case 'INCREMENT_TEMPLATE_USE': {
Store.incrementTemplateUse(data); break;
}
// Messaging
case 'INVITE_FROM_USERLIST': {
Store.inviteFromUserlist(data, cb); break;

View File

@@ -431,6 +431,8 @@ define([
// File picker
var FP = {};
var initFilePicker = function (cfg) {
// cfg.hidden means pre-loading the filepicker while keeping it hidden.
// if cfg.hidden is true and the iframe already exists, do nothing
if (!FP.$iframe) {
var config = {};
config.onFilePicked = function (data) {
@@ -449,7 +451,7 @@ define([
};
FP.$iframe = $('<iframe>', {id: 'sbox-filePicker-iframe'}).appendTo($('body'));
FP.picker = FilePicker.create(config);
} else {
} else if (!cfg.hidden) {
FP.$iframe.show();
FP.picker.refresh(cfg);
}
@@ -491,7 +493,8 @@ define([
res.push({
id: el,
name: data[el].filename || data[el].title || '?',
thumbnail: thumb
thumbnail: thumb,
used: data[el].used || 0
});
}));
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
www/common/tippy/tippy.min.js vendored Normal file

File diff suppressed because one or more lines are too long