Merge branch 'staging' into slide2
This commit is contained in:
commit
c3a07e879c
@ -41,6 +41,7 @@
|
|||||||
"bootstrap": "#v4.0.0-alpha.6",
|
"bootstrap": "#v4.0.0-alpha.6",
|
||||||
"diff-dom": "2.1.1",
|
"diff-dom": "2.1.1",
|
||||||
"nthen": "^0.1.5",
|
"nthen": "^0.1.5",
|
||||||
"open-sans-fontface": "^1.4.2"
|
"open-sans-fontface": "^1.4.2",
|
||||||
|
"bootstrap-tokenfield": "^0.12.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,8 @@ define(function() {
|
|||||||
users.
|
users.
|
||||||
*/
|
*/
|
||||||
config.loginSalt = '';
|
config.loginSalt = '';
|
||||||
|
config.minimum_password_length = 8;
|
||||||
|
|
||||||
config.badStateTimeout = 30000;
|
config.badStateTimeout = 30000;
|
||||||
|
|
||||||
config.applicationsIcon = {
|
config.applicationsIcon = {
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
define([
|
define([
|
||||||
'/api/config',
|
'/api/config',
|
||||||
'/common/hyperscript.js',
|
'/common/hyperscript.js',
|
||||||
'/common/cryptpad-common.js',
|
'/customize/messages.js',
|
||||||
'jquery'
|
'jquery'
|
||||||
], function (Config, h, Cryptpad, $) {
|
], function (Config, h, Msg, $) {
|
||||||
var Pages = {};
|
var Pages = {};
|
||||||
var Msg = Cryptpad.Messages;
|
|
||||||
var urlArgs = Config.requireConf.urlArgs;
|
var urlArgs = Config.requireConf.urlArgs;
|
||||||
|
|
||||||
var setHTML = function (e, html) {
|
var setHTML = function (e, html) {
|
||||||
@ -438,7 +437,7 @@ define([
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadingScreen = function () {
|
var loadingScreen = Pages.loadingScreen = function () {
|
||||||
return h('div#loading',
|
return h('div#loading',
|
||||||
h('div.loadingContainer', [
|
h('div.loadingContainer', [
|
||||||
h('img.cryptofist', {
|
h('img.cryptofist', {
|
||||||
@ -451,6 +450,12 @@ define([
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var hiddenLoader = function () {
|
||||||
|
var loader = loadingScreen();
|
||||||
|
loader.style.display = 'none';
|
||||||
|
return loader;
|
||||||
|
};
|
||||||
|
|
||||||
Pages['/user/'] = Pages['/user/index.html'] = function () {
|
Pages['/user/'] = Pages['/user/index.html'] = function () {
|
||||||
return h('div#container');
|
return h('div#container');
|
||||||
};
|
};
|
||||||
@ -526,6 +531,7 @@ define([
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
infopageFooter(),
|
infopageFooter(),
|
||||||
|
hiddenLoader(),
|
||||||
])];
|
])];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -559,6 +565,7 @@ define([
|
|||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
infopageFooter(),
|
infopageFooter(),
|
||||||
|
hiddenLoader(),
|
||||||
])];
|
])];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 9999;
|
z-index: 9999999;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
|||||||
@ -630,7 +630,7 @@ body .cryptpad-toolbar {
|
|||||||
.title {
|
.title {
|
||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
line-height: 25px;
|
line-height: 48px; //25px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
.pageTitle {
|
.pageTitle {
|
||||||
|
|||||||
@ -65,6 +65,12 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
|
|
||||||
|
.message {
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: @alertify-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
h1, h2, h3 {
|
h1, h2, h3 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
@ -85,6 +91,20 @@
|
|||||||
|
|
||||||
.dialog {
|
.dialog {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
/*
|
||||||
|
div.tokenfield {
|
||||||
|
.token {
|
||||||
|
//border: 1px solid red;
|
||||||
|
//color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
color: @colortheme_light-base;
|
||||||
|
background-color: @alertify-dialog-bg;
|
||||||
|
|
||||||
|
input[id$="tokenfield"][type="text"].token-input {
|
||||||
|
background-color: @alertify-dialog-bg !important;
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog, .alert {
|
.dialog, .alert {
|
||||||
@ -308,6 +328,5 @@
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
94
customize.dist/src/less2/include/tokenfield.less
Normal file
94
customize.dist/src/less2/include/tokenfield.less
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
.tokenfield_main () {
|
||||||
|
.tokenfield {
|
||||||
|
.unselectable () {
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unselectable();
|
||||||
|
height: auto;
|
||||||
|
min-height: 34px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
&.focus {
|
||||||
|
border-color: #66afe9;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
|
||||||
|
}
|
||||||
|
.token {
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 3px;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
background-color: #ededed;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin: -1px 5px 5px 0;
|
||||||
|
vertical-align: center;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
|
color: #222;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #b9b9b9;
|
||||||
|
}
|
||||||
|
&.invalid {
|
||||||
|
background: none;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
border-bottom: 1px dotted #d9534f;
|
||||||
|
}
|
||||||
|
&.invalid.active {
|
||||||
|
background: #ededed;
|
||||||
|
border: 1px solid #ededed;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
.token-label {
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding-left: 4px;
|
||||||
|
vertical-align: center;
|
||||||
|
}
|
||||||
|
.close {
|
||||||
|
font-family: Arial;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: 100%;
|
||||||
|
font-size: 1.1em;
|
||||||
|
margin-left: 5px;
|
||||||
|
float: none;
|
||||||
|
height: 100%;
|
||||||
|
vertical-align: center;
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
border-color: #52a8ec;
|
||||||
|
border-color: rgba(82, 168, 236, 0.8);
|
||||||
|
}
|
||||||
|
&.duplicate {
|
||||||
|
border-color: #ebccd1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.token-input {
|
||||||
|
background: none;
|
||||||
|
width: 0%; //60px;
|
||||||
|
min-width: 60px;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
box-shadow: none;
|
||||||
|
max-width: 100%;
|
||||||
|
&:focus {
|
||||||
|
border-color: transparent;
|
||||||
|
outline: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -129,6 +129,7 @@ define(function () {
|
|||||||
out.saveTemplatePrompt = "Choisir un titre pour ce modèle";
|
out.saveTemplatePrompt = "Choisir un titre pour ce modèle";
|
||||||
out.templateSaved = "Modèle enregistré !";
|
out.templateSaved = "Modèle enregistré !";
|
||||||
out.selectTemplate = "Sélectionner un modèle ou appuyer sur Échap";
|
out.selectTemplate = "Sélectionner un modèle ou appuyer sur Échap";
|
||||||
|
out.useTemplate = "Vous posséder des modèles pour ce type de pad, souhaitez-vous en utiliser un?";
|
||||||
|
|
||||||
out.previewButtonTitle = "Afficher ou cacher la prévisualisation de Markdown";
|
out.previewButtonTitle = "Afficher ou cacher la prévisualisation de Markdown";
|
||||||
|
|
||||||
|
|||||||
@ -131,6 +131,7 @@ define(function () {
|
|||||||
out.saveTemplatePrompt = "Choose a title for the template";
|
out.saveTemplatePrompt = "Choose a title for the template";
|
||||||
out.templateSaved = "Template saved!";
|
out.templateSaved = "Template saved!";
|
||||||
out.selectTemplate = "Select a template or press escape";
|
out.selectTemplate = "Select a template or press escape";
|
||||||
|
out.useTemplate = "You have available templates for that type of pad. Do you want to use one?";
|
||||||
|
|
||||||
out.previewButtonTitle = "Display or hide the Markdown preview mode";
|
out.previewButtonTitle = "Display or hide the Markdown preview mode";
|
||||||
|
|
||||||
@ -409,6 +410,8 @@ define(function () {
|
|||||||
out.register_importRecent = "Import pad history (Recommended)";
|
out.register_importRecent = "Import pad history (Recommended)";
|
||||||
out.register_acceptTerms = "I accept <a href='/terms.html' tabindex='-1'>the terms of service</a>";
|
out.register_acceptTerms = "I accept <a href='/terms.html' tabindex='-1'>the terms of service</a>";
|
||||||
out.register_passwordsDontMatch = "Passwords do not match!";
|
out.register_passwordsDontMatch = "Passwords do not match!";
|
||||||
|
out.register_passwordTooShort = "Passwords must be at least {0} characters long.";
|
||||||
|
|
||||||
out.register_mustAcceptTerms = "You must accept the terms of service.";
|
out.register_mustAcceptTerms = "You must accept the terms of service.";
|
||||||
out.register_mustRememberPass = "We cannot reset your password if you forget it. It's very important that you remember it! Please check the checkbox to confirm.";
|
out.register_mustRememberPass = "We cannot reset your password if you forget it. It's very important that you remember it! Please check the checkbox to confirm.";
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,7 @@ nThen((waitFor) => {
|
|||||||
sema.take((returnAfter) => {
|
sema.take((returnAfter) => {
|
||||||
Fs.stat(f, waitFor(returnAfter((err, st) => {
|
Fs.stat(f, waitFor(returnAfter((err, st) => {
|
||||||
if (err) { throw err; }
|
if (err) { throw err; }
|
||||||
|
st.filename = f;
|
||||||
dsFileStats[f.replace(/^.*\/([^\/\.]*)(\.ndjson)?$/, (all, a) => (a))] = st;
|
dsFileStats[f.replace(/^.*\/([^\/\.]*)(\.ndjson)?$/, (all, a) => (a))] = st;
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
@ -117,10 +118,28 @@ nThen((waitFor) => {
|
|||||||
});
|
});
|
||||||
}).nThen(() => {
|
}).nThen(() => {
|
||||||
if (process.argv.indexOf('--unpinned') > -1) {
|
if (process.argv.indexOf('--unpinned') > -1) {
|
||||||
|
const ot = process.argv.indexOf('--olderthan');
|
||||||
|
let before = Infinity;
|
||||||
|
if (ot > -1) {
|
||||||
|
before = new Date(process.argv[ot+1]);
|
||||||
|
if (isNaN(before)) {
|
||||||
|
throw new Error('--olderthan error [' + process.argv[ot+1] + '] not a valid date');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const bot = process.argv.indexOf('--blobsolderthan');
|
||||||
|
let blobsbefore = before;
|
||||||
|
if (bot > -1) {
|
||||||
|
blobsbefore = new Date(process.argv[bot+1]);
|
||||||
|
if (isNaN(blobsbefore)) {
|
||||||
|
throw new Error('--blobsolderthan error [' + process.argv[bot+1] + '] not a valid date');
|
||||||
|
}
|
||||||
|
}
|
||||||
Object.keys(dsFileStats).forEach((f) => {
|
Object.keys(dsFileStats).forEach((f) => {
|
||||||
if (!(f in pinned)) {
|
if (!(f in pinned)) {
|
||||||
console.log("./datastore/" + f.slice(0,2) + "/" + f + ".ndjson " +
|
const isBlob = dsFileStats[f].filename.indexOf('.ndjson') === -1;
|
||||||
dsFileStats[f].size + " " + (+dsFileStats[f].mtime));
|
if ((+dsFileStats[f].mtime) >= ((isBlob) ? blobsbefore : before)) { return; }
|
||||||
|
console.log(dsFileStats[f].filename + " " + dsFileStats[f].size + " " +
|
||||||
|
(+dsFileStats[f].mtime));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -7,9 +7,11 @@ define([
|
|||||||
'/common/notify.js',
|
'/common/notify.js',
|
||||||
'/common/visible.js',
|
'/common/visible.js',
|
||||||
'/common/tippy.min.js',
|
'/common/tippy.min.js',
|
||||||
|
'/customize/pages.js',
|
||||||
|
'/common/hyperscript.js',
|
||||||
|
'/bower_components/bootstrap-tokenfield/dist/bootstrap-tokenfield.js',
|
||||||
'css!/common/tippy.css',
|
'css!/common/tippy.css',
|
||||||
], function ($, Messages, Util, AppConfig, Alertify, Notify, Visible, Tippy) {
|
], function ($, Messages, Util, AppConfig, Alertify, Notify, Visible, Tippy, Pages, h) {
|
||||||
|
|
||||||
var UI = {};
|
var UI = {};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -20,11 +22,17 @@ define([
|
|||||||
// set notification timeout
|
// set notification timeout
|
||||||
Alertify._$$alertify.delay = AppConfig.notificationTimeout || 5000;
|
Alertify._$$alertify.delay = AppConfig.notificationTimeout || 5000;
|
||||||
|
|
||||||
var findCancelButton = UI.findCancelButton = function () {
|
var findCancelButton = UI.findCancelButton = function (root) {
|
||||||
|
if (root) {
|
||||||
|
return $(root).find('button.cancel').last();
|
||||||
|
}
|
||||||
return $('button.cancel').last();
|
return $('button.cancel').last();
|
||||||
};
|
};
|
||||||
|
|
||||||
var findOKButton = UI.findOKButton = function () {
|
var findOKButton = UI.findOKButton = function (root) {
|
||||||
|
if (root) {
|
||||||
|
return $(root).find('button.ok').last();
|
||||||
|
}
|
||||||
return $('button.ok').last();
|
return $('button.ok').last();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,7 +41,6 @@ define([
|
|||||||
switch (e.which) {
|
switch (e.which) {
|
||||||
case 27: // cancel
|
case 27: // cancel
|
||||||
if (typeof(no) === 'function') { no(e); }
|
if (typeof(no) === 'function') { no(e); }
|
||||||
no();
|
|
||||||
break;
|
break;
|
||||||
case 13: // enter
|
case 13: // enter
|
||||||
if (typeof(yes) === 'function') { yes(e); }
|
if (typeof(yes) === 'function') { yes(e); }
|
||||||
@ -49,21 +56,161 @@ define([
|
|||||||
$(window).off('keyup', handler);
|
$(window).off('keyup', handler);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var dialog = UI.dialog = {};
|
||||||
|
|
||||||
|
dialog.selectable = function (value) {
|
||||||
|
var input = h('input', {
|
||||||
|
type: 'text',
|
||||||
|
readonly: 'readonly',
|
||||||
|
});
|
||||||
|
$(input).val(value).click(function () {
|
||||||
|
input.select();
|
||||||
|
});
|
||||||
|
return input;
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.okButton = function () {
|
||||||
|
return h('button.ok', { tabindex: '2', }, Messages.okButton);
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.cancelButton = function () {
|
||||||
|
return h('button.cancel', { tabindex: '1'}, Messages.cancelButton);
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.message = function (text) {
|
||||||
|
return h('p.message', text);
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.textInput = function (opt) {
|
||||||
|
return h('input', opt || {
|
||||||
|
placeholder: '',
|
||||||
|
type: 'text',
|
||||||
|
'class': 'cp-text-input',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.nav = function (content) {
|
||||||
|
return h('nav', content || [
|
||||||
|
dialog.cancelButton(),
|
||||||
|
dialog.okButton(),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.frame = function (content) {
|
||||||
|
return h('div.alertify', [
|
||||||
|
h('div.dialog', [
|
||||||
|
h('div', content),
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
UI.tokenField = function (target) {
|
||||||
|
var t = {
|
||||||
|
element: target || h('input'),
|
||||||
|
};
|
||||||
|
var $t = t.tokenfield = $(t.element).tokenfield();
|
||||||
|
t.getTokens = function () {
|
||||||
|
return $t.tokenfield('getTokens').map(function (token) {
|
||||||
|
return token.value;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
t.preventDuplicates = function (cb) {
|
||||||
|
$t.on('tokenfield:createtoken', function (ev) {
|
||||||
|
var val;
|
||||||
|
if (t.getTokens().some(function (t) {
|
||||||
|
if (t === ev.attrs.value) { return ((val = t)); }
|
||||||
|
})) {
|
||||||
|
ev.preventDefault();
|
||||||
|
if (typeof(cb) === 'function') { cb(val); }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
t.setTokens = function (tokens) {
|
||||||
|
$t.tokenfield('setTokens',
|
||||||
|
tokens.map(function (token) {
|
||||||
|
return {
|
||||||
|
value: token,
|
||||||
|
label: token,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
t.focus = function () {
|
||||||
|
var $temp = $t.closest('.tokenfield').find('.token-input');
|
||||||
|
$temp.css('width', '20%');
|
||||||
|
$t.tokenfield('focusInput', $temp[0]);
|
||||||
|
};
|
||||||
|
|
||||||
|
return t;
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.tagPrompt = function (tags, cb) {
|
||||||
|
var input = dialog.textInput();
|
||||||
|
|
||||||
|
var tagger = dialog.frame([
|
||||||
|
dialog.message('make some tags'), // TODO translate
|
||||||
|
input,
|
||||||
|
dialog.nav(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
var field = UI.tokenField(input).preventDuplicates(function (val) {
|
||||||
|
UI.warn('Duplicate tag: ' + val); // TODO translate
|
||||||
|
});
|
||||||
|
|
||||||
|
var close = Util.once(function () {
|
||||||
|
var $t = $(tagger).fadeOut(150, function () { $t.remove(); });
|
||||||
|
});
|
||||||
|
|
||||||
|
var listener = listenForKeys(function () {}, function () {
|
||||||
|
close();
|
||||||
|
stopListening(listener);
|
||||||
|
});
|
||||||
|
|
||||||
|
var CB = Util.once(cb);
|
||||||
|
findOKButton(tagger).click(function () {
|
||||||
|
var tokens = field.getTokens();
|
||||||
|
close();
|
||||||
|
CB(tokens);
|
||||||
|
});
|
||||||
|
findCancelButton(tagger).click(function () {
|
||||||
|
close();
|
||||||
|
CB(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// :(
|
||||||
|
setTimeout(function () {
|
||||||
|
field.setTokens(tags);
|
||||||
|
field.focus();
|
||||||
|
});
|
||||||
|
|
||||||
|
return tagger;
|
||||||
|
};
|
||||||
|
|
||||||
UI.alert = function (msg, cb, force) {
|
UI.alert = function (msg, cb, force) {
|
||||||
cb = cb || function () {};
|
cb = cb || function () {};
|
||||||
if (force !== true) { msg = Util.fixHTML(msg); }
|
if (typeof(msg) === 'string' && force !== true) {
|
||||||
var close = function () {
|
msg = Util.fixHTML(msg);
|
||||||
findOKButton().click();
|
}
|
||||||
};
|
var ok = dialog.okButton();
|
||||||
var keyHandler = listenForKeys(close, close);
|
var frame = dialog.frame([
|
||||||
Alertify
|
dialog.message(msg),
|
||||||
.okBtn(Messages.okButton || 'OK')
|
dialog.nav(ok),
|
||||||
.alert(msg, function (ev) {
|
]);
|
||||||
cb(ev);
|
|
||||||
stopListening(keyHandler);
|
var listener;
|
||||||
});
|
var close = Util.once(function () {
|
||||||
window.setTimeout(function () {
|
$(frame).fadeOut(150, function () { $(this).remove(); });
|
||||||
findOKButton().focus();
|
stopListening(listener);
|
||||||
|
});
|
||||||
|
listener = listenForKeys(close, close);
|
||||||
|
var $ok = $(ok).click(close);
|
||||||
|
|
||||||
|
document.body.appendChild(frame);
|
||||||
|
setTimeout(function () {
|
||||||
|
$ok.focus();
|
||||||
if (typeof(UI.notify) === 'function') {
|
if (typeof(UI.notify) === 'function') {
|
||||||
UI.notify();
|
UI.notify();
|
||||||
}
|
}
|
||||||
@ -165,7 +312,7 @@ define([
|
|||||||
*/
|
*/
|
||||||
UI.spinner = function (parent) {
|
UI.spinner = function (parent) {
|
||||||
var $target = $('<span>', {
|
var $target = $('<span>', {
|
||||||
'class': 'fa fa-spinner fa-pulse fa-4x fa-fw'
|
'class': 'fa fa-circle-o-notch fa-spin fa-4x fa-fw',
|
||||||
}).hide();
|
}).hide();
|
||||||
|
|
||||||
$(parent).append($target);
|
$(parent).append($target);
|
||||||
@ -206,16 +353,15 @@ define([
|
|||||||
}
|
}
|
||||||
$container = $loading.find('.loadingContainer');
|
$container = $loading.find('.loadingContainer');
|
||||||
} else {
|
} else {
|
||||||
$loading = $('<div>', {id: LOADING});
|
$loading = $(Pages.loadingScreen());
|
||||||
$container = $('<div>', {'class': 'loadingContainer'});
|
$container = $loading.find('.loadingContainer');
|
||||||
if (!hideLogo) {
|
if (hideLogo) {
|
||||||
$container.append('<img class="cryptofist" src="/customize/cryptofist_small.png" />');
|
$loading.find('img').hide();
|
||||||
|
} else {
|
||||||
|
$loading.find('img').show();
|
||||||
}
|
}
|
||||||
var $spinner = $('<div>', {'class': 'spinnerContainer'});
|
var $spinner = $loading.find('.spinnerContainer');
|
||||||
UI.spinner($spinner).show();
|
$spinner.show();
|
||||||
var $text = $('<p>').text(loadingText || Messages.loading);
|
|
||||||
$container.append($spinner).append($text);
|
|
||||||
$loading.append($container);
|
|
||||||
$('body').append($loading);
|
$('body').append($loading);
|
||||||
}
|
}
|
||||||
if (Messages.tips && !hideTips) {
|
if (Messages.tips && !hideTips) {
|
||||||
|
|||||||
@ -170,5 +170,15 @@ define([], function () {
|
|||||||
return parts[0];
|
return parts[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* for wrapping async functions such that they can only be called once */
|
||||||
|
Util.once = function (f) {
|
||||||
|
var called;
|
||||||
|
return function () {
|
||||||
|
if (called) { return; }
|
||||||
|
called = true;
|
||||||
|
f.apply(this, Array.prototype.slice.call(arguments));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
return Util;
|
return Util;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,6 +5,13 @@ define([
|
|||||||
var Cred = {};
|
var Cred = {};
|
||||||
var Scrypt = window.scrypt;
|
var Scrypt = window.scrypt;
|
||||||
|
|
||||||
|
Cred.MINIMUM_PASSWORD_LENGTH = typeof(AppConfig.minimum_password_length) === 'number'?
|
||||||
|
AppConfig.minimum_password_length: 8;
|
||||||
|
|
||||||
|
Cred.isLongEnoughPassword = function (passwd) {
|
||||||
|
return passwd.length >= Cred.MINIMUM_PASSWORD_LENGTH;
|
||||||
|
};
|
||||||
|
|
||||||
var isString = Cred.isString = function (x) {
|
var isString = Cred.isString = function (x) {
|
||||||
return typeof(x) === 'string';
|
return typeof(x) === 'string';
|
||||||
};
|
};
|
||||||
|
|||||||
@ -81,6 +81,8 @@ define([
|
|||||||
common.addTooltips = UI.addTooltips;
|
common.addTooltips = UI.addTooltips;
|
||||||
common.clearTooltips = UI.clearTooltips;
|
common.clearTooltips = UI.clearTooltips;
|
||||||
common.importContent = UI.importContent;
|
common.importContent = UI.importContent;
|
||||||
|
common.tokenField = UI.tokenField;
|
||||||
|
common.dialog = UI.dialog;
|
||||||
|
|
||||||
// import common utilities for export
|
// import common utilities for export
|
||||||
common.find = Util.find;
|
common.find = Util.find;
|
||||||
@ -1391,6 +1393,21 @@ define([
|
|||||||
})
|
})
|
||||||
.click(prepareFeedback(type));
|
.click(prepareFeedback(type));
|
||||||
break;
|
break;
|
||||||
|
case 'hashtag':
|
||||||
|
button = $('<button>', {
|
||||||
|
'class': 'fa fa-hashtag',
|
||||||
|
})
|
||||||
|
.click(prepareFeedback(type))
|
||||||
|
.click(function () {
|
||||||
|
// TODO fetch pad tags before presenting dialog to user
|
||||||
|
var dialog = UI.dialog.tagPrompt([], function (tags) {
|
||||||
|
if (!Array.isArray(tags)) { return; }
|
||||||
|
console.error(tags);
|
||||||
|
// TODO do something with the tags the user entered
|
||||||
|
});
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
button = $('<button>', {
|
button = $('<button>', {
|
||||||
'class': "fa fa-question",
|
'class': "fa fa-question",
|
||||||
@ -1940,7 +1957,7 @@ define([
|
|||||||
};
|
};
|
||||||
var $userAdmin = createDropdown(dropdownConfigUser);
|
var $userAdmin = createDropdown(dropdownConfigUser);
|
||||||
|
|
||||||
var oldUrl;
|
var oldUrl = '';
|
||||||
if (account && !config.static && store) {
|
if (account && !config.static && store) {
|
||||||
var $avatar = $userAdmin.find('.cp-dropdown-button-title');
|
var $avatar = $userAdmin.find('.cp-dropdown-button-title');
|
||||||
var updateButton = function (newName) {
|
var updateButton = function (newName) {
|
||||||
@ -1950,7 +1967,7 @@ define([
|
|||||||
if (oldUrl === url) { return; }
|
if (oldUrl === url) { return; }
|
||||||
oldUrl = url;
|
oldUrl = url;
|
||||||
$avatar.html('');
|
$avatar.html('');
|
||||||
common.displayAvatar($avatar, url, newName, function ($img) {
|
common.displayAvatar($avatar, url, newName || Messages.anonymous, function ($img) {
|
||||||
if ($img) {
|
if ($img) {
|
||||||
$userAdmin.find('button').addClass('avatar');
|
$userAdmin.find('button').addClass('avatar');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -88,6 +88,7 @@ define([
|
|||||||
// validate inputs
|
// validate inputs
|
||||||
if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); }
|
if (!Cred.isValidUsername(uname)) { return void cb('INVAL_USER'); }
|
||||||
if (!Cred.isValidPassword(passwd)) { return void cb('INVAL_PASS'); }
|
if (!Cred.isValidPassword(passwd)) { return void cb('INVAL_PASS'); }
|
||||||
|
if (!Cred.isLongEnoughPassword(passwd)) { return void cb('PASS_TOO_SHORT'); }
|
||||||
|
|
||||||
Cred.deriveFromPassphrase(uname, passwd, 128, function (bytes) {
|
Cred.deriveFromPassphrase(uname, passwd, 128, function (bytes) {
|
||||||
// results...
|
// results...
|
||||||
|
|||||||
@ -382,9 +382,9 @@ define([
|
|||||||
var $displayName = $userAdmin.find('.'+displayNameCls);
|
var $displayName = $userAdmin.find('.'+displayNameCls);
|
||||||
|
|
||||||
var $avatar = $userAdmin.find('.cp-dropdown-button-title');
|
var $avatar = $userAdmin.find('.cp-dropdown-button-title');
|
||||||
var oldUrl;
|
|
||||||
var loadingAvatar;
|
var loadingAvatar;
|
||||||
var to;
|
var to;
|
||||||
|
var oldUrl = '';
|
||||||
var updateButton = function () {
|
var updateButton = function () {
|
||||||
var myData = metadataMgr.getUserData();
|
var myData = metadataMgr.getUserData();
|
||||||
if (!myData) { return; }
|
if (!myData) { return; }
|
||||||
@ -400,7 +400,7 @@ define([
|
|||||||
$displayName.text(newName || Messages.anonymous);
|
$displayName.text(newName || Messages.anonymous);
|
||||||
if (accountName && oldUrl !== url) {
|
if (accountName && oldUrl !== url) {
|
||||||
$avatar.html('');
|
$avatar.html('');
|
||||||
UI.displayAvatar(Common, $avatar, url, newName, function ($img) {
|
UI.displayAvatar(Common, $avatar, url, newName || Messages.anonymous, function ($img) {
|
||||||
oldUrl = url;
|
oldUrl = url;
|
||||||
if ($img) {
|
if ($img) {
|
||||||
$userAdmin.find('button').addClass('cp-avatar');
|
$userAdmin.find('button').addClass('cp-avatar');
|
||||||
@ -462,28 +462,37 @@ define([
|
|||||||
UI.openTemplatePicker = function (common) {
|
UI.openTemplatePicker = function (common) {
|
||||||
var metadataMgr = common.getMetadataMgr();
|
var metadataMgr = common.getMetadataMgr();
|
||||||
var type = metadataMgr.getMetadataLazy().type;
|
var type = metadataMgr.getMetadataLazy().type;
|
||||||
var first = true; // We can only pick a template once (for a new document)
|
var sframeChan = common.getSframeChannel();
|
||||||
var fileDialogCfg = {
|
|
||||||
onSelect: function (data) {
|
var onConfirm = function (yes) {
|
||||||
if (data.type === type && first) {
|
if (!yes) { return; }
|
||||||
Cryptpad.addLoadingScreen({hideTips: true});
|
var first = true; // We can only pick a template once (for a new document)
|
||||||
var sframeChan = common.getSframeChannel();
|
var fileDialogCfg = {
|
||||||
sframeChan.query('Q_TEMPLATE_USE', data.href, function () {
|
onSelect: function (data) {
|
||||||
first = false;
|
if (data.type === type && first) {
|
||||||
Cryptpad.removeLoadingScreen();
|
Cryptpad.addLoadingScreen({hideTips: true});
|
||||||
common.feedback('TEMPLATE_USED');
|
sframeChan.query('Q_TEMPLATE_USE', data.href, function () {
|
||||||
});
|
first = false;
|
||||||
return;
|
Cryptpad.removeLoadingScreen();
|
||||||
|
common.feedback('TEMPLATE_USED');
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
common.initFilePicker(fileDialogCfg);
|
||||||
|
var pickerCfg = {
|
||||||
|
types: [type],
|
||||||
|
where: ['template']
|
||||||
|
};
|
||||||
|
common.openFilePicker(pickerCfg);
|
||||||
|
};
|
||||||
|
|
||||||
|
sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) {
|
||||||
|
if (data) {
|
||||||
|
Cryptpad.confirm(Messages.useTemplate, onConfirm);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
common.initFilePicker(fileDialogCfg);
|
|
||||||
var pickerCfg = {
|
|
||||||
types: [type],
|
|
||||||
where: ['template']
|
|
||||||
};
|
|
||||||
console.log(pickerCfg);
|
|
||||||
common.openFilePicker(pickerCfg);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return UI;
|
return UI;
|
||||||
|
|||||||
@ -312,6 +312,10 @@ define([
|
|||||||
sframeChan.on('Q_TEMPLATE_USE', function (href, cb) {
|
sframeChan.on('Q_TEMPLATE_USE', function (href, cb) {
|
||||||
Cryptpad.useTemplate(href, Cryptget, cb);
|
Cryptpad.useTemplate(href, Cryptget, cb);
|
||||||
});
|
});
|
||||||
|
sframeChan.on('Q_TEMPLATE_EXIST', function (type, cb) {
|
||||||
|
var hasTemplate = Cryptpad.listTemplates(type).length > 0;
|
||||||
|
cb(hasTemplate);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
sframeChan.ready();
|
sframeChan.ready();
|
||||||
|
|||||||
@ -107,6 +107,8 @@ define({
|
|||||||
|
|
||||||
// Template picked, replace the content of the pad
|
// Template picked, replace the content of the pad
|
||||||
'Q_TEMPLATE_USE': true,
|
'Q_TEMPLATE_USE': true,
|
||||||
|
// Check if we have template(s) for the selected pad type
|
||||||
|
'Q_TEMPLATE_EXIST': true,
|
||||||
|
|
||||||
// File upload queries and events
|
// File upload queries and events
|
||||||
'Q_UPLOAD_FILE': true,
|
'Q_UPLOAD_FILE': true,
|
||||||
|
|||||||
@ -516,29 +516,11 @@ define([
|
|||||||
$('<h3>').text(Messages.fileEmbedTitle).appendTo($content);
|
$('<h3>').text(Messages.fileEmbedTitle).appendTo($content);
|
||||||
var $script = $('<p>').text(Messages.fileEmbedScript).appendTo($content);
|
var $script = $('<p>').text(Messages.fileEmbedScript).appendTo($content);
|
||||||
$('<br>').appendTo($script);
|
$('<br>').appendTo($script);
|
||||||
var scriptId = uid();
|
$script.append(Cryptpad.dialog.selectable(Cryptpad.getMediatagScript()));
|
||||||
$('<input>', {
|
|
||||||
type: 'text',
|
|
||||||
id: scriptId,
|
|
||||||
readonly: 'readonly',
|
|
||||||
value: Cryptpad.getMediatagScript(),
|
|
||||||
}).appendTo($script);
|
|
||||||
var $tag = $('<p>').text(Messages.fileEmbedTag).appendTo($content);
|
var $tag = $('<p>').text(Messages.fileEmbedTag).appendTo($content);
|
||||||
$('<br>').appendTo($tag);
|
$('<br>').appendTo($tag);
|
||||||
var tagId = uid();
|
$tag.append(Cryptpad.dialog.selectable(Cryptpad.getMediatagFromHref(url)));
|
||||||
$('<input>', {
|
Cryptpad.alert($content[0], null, true);
|
||||||
type:'text',
|
|
||||||
id: tagId,
|
|
||||||
readonly:'readonly',
|
|
||||||
value:Cryptpad.getMediatagFromHref(url),
|
|
||||||
}).appendTo($tag);
|
|
||||||
Cryptpad.alert($content.html(), null, true);
|
|
||||||
$('#'+scriptId).click(function () {
|
|
||||||
this.select();
|
|
||||||
});
|
|
||||||
$('#'+tagId).click(function () {
|
|
||||||
this.select();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
toolbar.$leftside.append($shareBlock);
|
toolbar.$leftside.append($shareBlock);
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
'/common/login.js'
|
'/common/login.js',
|
||||||
|
|
||||||
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
|
'less!/customize/src/less/loading.less',
|
||||||
], function ($, Cryptpad, Login) {
|
], function ($, Cryptpad, Login) {
|
||||||
$(function () {
|
$(function () {
|
||||||
var $main = $('#mainBlock');
|
var $main = $('#mainBlock');
|
||||||
@ -72,7 +75,10 @@ define([
|
|||||||
|
|
||||||
// setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
|
// setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
Cryptpad.addLoadingScreen({loadingText: Messages.login_hashing});
|
Cryptpad.addLoadingScreen({
|
||||||
|
loadingText: Messages.login_hashing,
|
||||||
|
hideTips: true,
|
||||||
|
});
|
||||||
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
|
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
loginReady(function () {
|
loginReady(function () {
|
||||||
|
|||||||
@ -4,7 +4,10 @@ define([
|
|||||||
'/common/cryptpad-common.js',
|
'/common/cryptpad-common.js',
|
||||||
'/common/test.js',
|
'/common/test.js',
|
||||||
'/common/credential.js', // preloaded for login.js
|
'/common/credential.js', // preloaded for login.js
|
||||||
], function ($, Login, Cryptpad, Test) {
|
|
||||||
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
|
'less!/customize/src/less/loading.less',
|
||||||
|
], function ($, Login, Cryptpad, Test, Cred) {
|
||||||
var Messages = Cryptpad.Messages;
|
var Messages = Cryptpad.Messages;
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
@ -128,11 +131,15 @@ define([
|
|||||||
registering = true;
|
registering = true;
|
||||||
// setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
|
// setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
Cryptpad.addLoadingScreen({loadingText: Messages.login_hashing});
|
Cryptpad.addLoadingScreen({
|
||||||
|
loadingText: Messages.login_hashing,
|
||||||
|
hideTips: true,
|
||||||
|
});
|
||||||
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
|
// We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function () {
|
||||||
Login.loginOrRegister(uname, passwd, true, function (err, result) {
|
Login.loginOrRegister(uname, passwd, true, function (err, result) {
|
||||||
var proxy = result.proxy;
|
var proxy;
|
||||||
|
if (result) { proxy = result.proxy; }
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
@ -157,6 +164,16 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'PASS_TOO_SHORT':
|
||||||
|
Cryptpad.removeLoadingScreen(function () {
|
||||||
|
var warning = Messages._getKey('register_passwordTooShort', [
|
||||||
|
Cred.MINIMUM_PASSWORD_LENGTH
|
||||||
|
]);
|
||||||
|
Cryptpad.alert(warning, function () {
|
||||||
|
registering = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
case 'ALREADY_REGISTERED':
|
case 'ALREADY_REGISTERED':
|
||||||
// logMeIn should reset registering = false
|
// logMeIn should reset registering = false
|
||||||
Cryptpad.removeLoadingScreen(function () {
|
Cryptpad.removeLoadingScreen(function () {
|
||||||
@ -193,7 +210,7 @@ define([
|
|||||||
logMeIn(result);
|
logMeIn(result);
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
}, 100);
|
}, 200);
|
||||||
}, {
|
}, {
|
||||||
ok: Messages.register_writtenPassword,
|
ok: Messages.register_writtenPassword,
|
||||||
cancel: Messages.register_cancel,
|
cancel: Messages.register_cancel,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user