-
diff --git a/www/drive/main.js b/www/drive/main.js
index 39b5450fc..d4ac6cce2 100644
--- a/www/drive/main.js
+++ b/www/drive/main.js
@@ -297,6 +297,7 @@ define([
};
$content.on('mousedown', function (e) {
if (e.which !== 1) { return; }
+ $content.focus();
sel.down = true;
if (!e.ctrlKey) { removeSelected(); }
var rect = e.currentTarget.getBoundingClientRect();
@@ -359,13 +360,15 @@ define([
};
$content.mousemove(sel.move);
});
- $content.on('mouseup', function (e) {
+ $(ifrw).on('mouseup', function (e) {
+ if (!sel.down) { return; }
if (e.which !== 1) { return; }
sel.down = false;
sel.$selectBox.hide();
$content.off('mousemove', sel.move);
delete sel.move;
$content.find('.selectedTmp').removeClass('selectedTmp').addClass('selected');
+ e.stopPropagation();
});
$(ifrw).keydown(function (e) {
@@ -520,6 +523,10 @@ define([
placeholder: name,
value: name
}).data('path', path);
+
+ // Stop propagation on keydown to avoid issues with arrow keys
+ $input.on('keydown', function (e) { e.stopPropagation(); });
+
$input.on('keyup', function (e) {
if (e.which === 13) {
removeInput(true);
@@ -560,7 +567,7 @@ define([
var filterContextMenu = function ($menu, paths) {
//var path = $element.data('path');
- if (!paths || paths.length === 0) { console.error('no paths'); }
+ if (!paths || paths.length === 0) { logError('no paths'); }
var hide = [];
var hasFolder = false;
@@ -763,6 +770,7 @@ define([
var displayMenu = function (e, $menu) {
$menu.css({ display: "block" });
+ if (APP.mobile()) { return; }
var h = $menu.outerHeight();
var w = $menu.outerWidth();
var wH = window.innerHeight;
@@ -1785,7 +1793,7 @@ define([
module.resetTree();
// in history mode we want to focus the version number input
- if (!history.isHistoryMode) { $tree.find('#searchInput').focus(); }
+ if (!history.isHistoryMode && !APP.mobile()) { $tree.find('#searchInput').focus(); }
$tree.find('#searchInput')[0].selectionStart = getSearchCursor();
$tree.find('#searchInput')[0].selectionEnd = getSearchCursor();
@@ -2028,16 +2036,19 @@ define([
var search = APP.Search = {};
var createSearch = function ($container) {
var isInSearch = currentPath[0] === SEARCH;
- var $div = $('
', {'id': 'searchContainer'});
+ var $div = $('
', {'id': 'searchContainer', 'class': 'unselectable'});
var $input = $('', {
id: 'searchInput',
type: 'text',
+ draggable: false,
+ tabindex: 1,
placeholder: Messages.fm_searchPlaceholder
}).keyup(function (e) {
if (search.to) { window.clearTimeout(search.to); }
if ([38, 39, 40, 41].indexOf(e.which) !== -1) {
if (!$input.val()) {
$input.blur();
+ $content.focus();
return;
} else {
e.stopPropagation();
@@ -2056,6 +2067,7 @@ define([
if (!filesOp.comparePath(newLocation, currentPath.slice())) { displayDirectory(newLocation); }
return;
}
+ if (APP.mobile()) { return; }
search.to = window.setTimeout(function () {
if (!isInSearchTmp) { search.oldLocation = currentPath.slice(); }
var newLocation = [SEARCH, $input.val()];
@@ -2163,7 +2175,7 @@ define([
Cryptpad.getFileSize(el, function (e, bytes) {
if (e) {
// there was a problem with the RPC
- console.error(e);
+ logError(e);
// but we don't want to break the interface.
// continue as if there was no RPC
@@ -2239,7 +2251,7 @@ define([
if (paths.length !== 1) { return; }
var el = filesOp.find(paths[0].path);
getProperties(el, function (e, $prop) {
- if (e) { return void console.error(e); }
+ if (e) { return void logError(e); }
Cryptpad.alert('', undefined, true);
$('.alertify .msg').html("").append($prop);
});
@@ -2279,7 +2291,7 @@ define([
if (paths.length !== 1) { return; }
var el = filesOp.find(paths[0].path);
getProperties(el, function (e, $prop) {
- if (e) { return void console.error(e); }
+ if (e) { return void logError(e); }
Cryptpad.alert('', undefined, true);
$('.alertify .msg').html("").append($prop);
});
@@ -2369,9 +2381,18 @@ define([
module.hideMenu();
});
- $appContainer.on('mousedown', function (e) {
+ // Chrome considers the double-click means "select all" in the window
+ $content.on('mousedown', function (e) {
+ $content.focus();
+ e.preventDefault();
+ });
+ $appContainer.on('mouseup', function (e) {
+ if (sel.down) { return; }
if (e.which !== 1) { return ; }
removeSelected(e);
+ });
+ $appContainer.on('click', function (e) {
+ if (e.which !== 1) { return ; }
removeInput();
module.hideMenu(e);
hideNewButton();
@@ -2514,7 +2535,6 @@ define([
setEditable(!bool);
if (!bool && update) {
history.onLeaveHistory();
- //init(); //TODO real proxy here
}
};
@@ -2667,33 +2687,20 @@ define([
}
/* add a history button */
- var histConfig = {};
- histConfig.onRender = function (val) {
- if (typeof val === "undefined") { return; }
- try {
+ var histConfig = {
+ onLocal: function () {
+ proxy.drive = history.currentObj.drive;
+ },
+ onRemote: function () {},
+ setHistory: setHistory,
+ applyVal: function (val) {
var obj = JSON.parse(val || '{}');
history.currentObj = obj;
history.onEnterHistory(obj);
- } catch (e) {
- // Probably a parse error
- console.error(e);
- }
- };
- histConfig.onClose = function () {
- // Close button clicked
- setHistory(false, true);
- };
- histConfig.onRevert = function () {
- // Revert button clicked
- setHistory(false, false);
- proxy.drive = history.currentObj.drive;
- };
- histConfig.onReady = function () {
- // Called when the history is loaded and the UI displayed
- setHistory(true);
+ },
+ $toolbar: APP.$bar,
+ href: window.location.origin + window.location.pathname + APP.hash
};
- histConfig.$toolbar = APP.$bar;
- histConfig.href = window.location.origin + window.location.pathname + APP.hash;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
diff --git a/www/file/main.js b/www/file/main.js
index 223fcc41e..66e0f6c25 100644
--- a/www/file/main.js
+++ b/www/file/main.js
@@ -2,7 +2,7 @@ define([
'jquery',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js',
- '/common/toolbar.js',
+ '/common/toolbar2.js',
'/common/cryptpad-common.js',
'/common/visible.js',
'/common/notify.js',
@@ -24,6 +24,8 @@ define([
Cryptpad.addLoadingScreen();
+ var Title;
+
var myFile;
var myDataType;
@@ -68,17 +70,13 @@ define([
var uri = ['', 'blob', id.slice(0,2), id].join('/');
console.log("encrypted blob is now available as %s", uri);
- // TODO use cryptpad-common utilities
- window.location.hash = [
- '',
- 2,
- Cryptpad.hexToBase64(id).replace(/\//g, '-'),
- Nacl.util.encodeBase64(key).replace(/\//g, '-'),
- ''
- ].join('/');
+ var b64Key = Nacl.util.encodeBase64(key);
+ window.location.hash = Cryptpad.getFileHashFromKeys(id, b64Key);
$form.hide();
+ APP.toolbar.addElement(['fileshare'], {});
+
// check if the uploaded file can be decrypted
var newU8 = FileCrypto.joinChunks(chunks);
FileCrypto.decrypt(newU8, key, function (e, res) {
@@ -88,7 +86,8 @@ define([
myDataType = res.metadata.type;
var defaultName = Cryptpad.getDefaultName(Cryptpad.parsePadUrl(window.location.href));
- APP.updateTitle(title || defaultName);
+ Title.updateTitle(title || defaultName);
+ APP.toolbar.title.show();
Cryptpad.alert("successfully uploaded: " + title);
});
});
@@ -133,9 +132,6 @@ define([
uploadMode = true;
}
- var parsed = Cryptpad.parsePadUrl(window.location.href);
- var defaultName = Cryptpad.getDefaultName(parsed);
-
var getTitle = function () {
var pad = Cryptpad.getRelativeHref(window.location.href);
var fo = Cryptpad.getStore().getProxy().fo;
@@ -143,27 +139,6 @@ define([
return data ? data.title : undefined;
};
- var updateTitle = APP.updateTitle = function (newTitle) {
- Cryptpad.renamePad(newTitle, function (err, data) {
- if (err) {
- console.log("Couldn't set pad title");
- console.error(err);
- return;
- }
- document.title = newTitle;
- $bar.find('.' + Toolbar.constants.title).find('span.title').text(data);
- $bar.find('.' + Toolbar.constants.title).find('input').val(data);
- });
- };
-
- var suggestName = function () {
- return document.title || getTitle() || '';
- };
-
- var renameCb = function (err, title) {
- document.title = title;
- };
-
var exportFile = function () {
var suggestion = document.title;
Cryptpad.prompt(Messages.exportPrompt,
@@ -174,33 +149,33 @@ define([
});
};
- var displayed = ['useradmin', 'newpad', 'limit'];
+ Title = Cryptpad.createTitle({}, function(){}, Cryptpad);
+
+ var displayed = ['title', 'useradmin', 'newpad', 'limit'];
if (secret && hexFileName) {
- displayed.push('share');
+ displayed.push('fileshare');
}
var configTb = {
displayed: displayed,
ifrw: ifrw,
common: Cryptpad,
- title: {
- onRename: renameCb,
- defaultName: defaultName,
- suggestName: suggestName
- },
- share: {
- secret: secret,
- channel: hexFileName
- },
- hideDisplayName: true
+ title: Title.getTitleConfig(),
+ hideDisplayName: true,
+ $container: $bar
};
- Toolbar.create($bar, null, null, null, null, configTb);
- var $rightside = $bar.find('.' + Toolbar.constants.rightside);
+ var toolbar = APP.toolbar = Toolbar.create(configTb);
+
+ Title.setToolbar(toolbar);
+
+ if (uploadMode) { toolbar.title.hide(); }
+
+ var $rightside = toolbar.$rightside;
var $export = Cryptpad.createButton('export', true, {}, exportFile);
$rightside.append($export);
- updateTitle(Cryptpad.initialName || getTitle() || defaultName);
+ Title.updateTitle(Cryptpad.initialName || getTitle() || Title.defaultTitle);
if (!uploadMode) {
var src = Cryptpad.getBlobPathFromHex(hexFileName);
@@ -219,7 +194,7 @@ define([
var title = document.title = data.metadata.name;
myFile = data.content;
myDataType = data.metadata.type;
- updateTitle(title || defaultName);
+ Title.updateTitle(title || Title.defaultTitle);
Cryptpad.removeLoadingScreen();
});
});
diff --git a/www/login/main.js b/www/login/main.js
index 973cd985f..7a677cebb 100644
--- a/www/login/main.js
+++ b/www/login/main.js
@@ -57,65 +57,68 @@ define([
});
$('button.login').click(function () {
- Cryptpad.addLoadingScreen(Messages.login_hashing);
- // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
+ // setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
window.setTimeout(function () {
- loginReady(function () {
- var uname = $uname.val();
- var passwd = $passwd.val();
- Login.loginOrRegister(uname, passwd, false, function (err, result) {
- if (!err) {
- var proxy = result.proxy;
+ Cryptpad.addLoadingScreen(Messages.login_hashing);
+ // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
+ window.setTimeout(function () {
+ loginReady(function () {
+ var uname = $uname.val();
+ var passwd = $passwd.val();
+ Login.loginOrRegister(uname, passwd, false, function (err, result) {
+ if (!err) {
+ var proxy = result.proxy;
- // successful validation and user already exists
- // set user hash in localStorage and redirect to drive
- if (!proxy.login_name) {
- result.proxy.login_name = result.userName;
- }
+ // successful validation and user already exists
+ // set user hash in localStorage and redirect to drive
+ if (!proxy.login_name) {
+ result.proxy.login_name = result.userName;
+ }
- proxy.edPrivate = result.edPrivate;
- proxy.edPublic = result.edPublic;
+ proxy.edPrivate = result.edPrivate;
+ proxy.edPublic = result.edPublic;
- Cryptpad.feedback('LOGIN', true);
- Cryptpad.whenRealtimeSyncs(result.realtime, function() {
- Cryptpad.login(result.userHash, result.userName, function () {
- if (sessionStorage.redirectTo) {
- var h = sessionStorage.redirectTo;
- var parser = document.createElement('a');
- parser.href = h;
- if (parser.origin === window.location.origin) {
- delete sessionStorage.redirectTo;
- window.location.href = h;
- return;
+ Cryptpad.feedback('LOGIN', true);
+ Cryptpad.whenRealtimeSyncs(result.realtime, function() {
+ Cryptpad.login(result.userHash, result.userName, function () {
+ if (sessionStorage.redirectTo) {
+ var h = sessionStorage.redirectTo;
+ var parser = document.createElement('a');
+ parser.href = h;
+ if (parser.origin === window.location.origin) {
+ delete sessionStorage.redirectTo;
+ window.location.href = h;
+ return;
+ }
}
- }
- window.location.href = '/drive/';
- });
- });
- return;
- }
- switch (err) {
- case 'NO_SUCH_USER':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_noSuchUser);
- });
- break;
- case 'INVAL_USER':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_invalUser);
+ window.location.href = '/drive/';
+ });
});
- break;
- case 'INVAL_PASS':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_invalPass);
- });
- break;
- default: // UNHANDLED ERROR
- Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
- }
+ return;
+ }
+ switch (err) {
+ case 'NO_SUCH_USER':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_noSuchUser);
+ });
+ break;
+ case 'INVAL_USER':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_invalUser);
+ });
+ break;
+ case 'INVAL_PASS':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_invalPass);
+ });
+ break;
+ default: // UNHANDLED ERROR
+ Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
+ }
+ });
});
- });
- }, 0);
+ }, 0);
+ }, 100);
});
});
});
diff --git a/www/pad/main.js b/www/pad/main.js
index 50e35f2dc..635ea0087 100644
--- a/www/pad/main.js
+++ b/www/pad/main.js
@@ -499,31 +499,13 @@ define([
}
/* add a history button */
- var histConfig = {};
- histConfig.onRender = function (val) {
- if (typeof val === "undefined") { return; }
- try {
- applyHjson(val || '["BODY",{},[]]');
- } catch (e) {
- // Probably a parse error
- console.error(e);
- }
- };
- histConfig.onClose = function () {
- // Close button clicked
- setHistory(false, true);
- };
- histConfig.onRevert = function () {
- // Revert button clicked
- setHistory(false, false);
- realtimeOptions.onLocal();
- realtimeOptions.onRemote();
- };
- histConfig.onReady = function () {
- // Called when the history is loaded and the UI displayed
- setHistory(true);
+ var histConfig = {
+ onLocal: realtimeOptions.onLocal(),
+ onRemote: realtimeOptions.onRemote(),
+ setHistory: setHistory,
+ applyVal: function (val) { applyHjson(val || '["BODY",{},[]]'); },
+ $toolbar: $bar
};
- histConfig.$toolbar = $bar;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
diff --git a/www/register/main.js b/www/register/main.js
index 6e97e2a93..bafe55423 100644
--- a/www/register/main.js
+++ b/www/register/main.js
@@ -101,57 +101,63 @@ define([
function (yes) {
if (!yes) { return; }
- Cryptpad.addLoadingScreen(Messages.login_hashing);
- Login.loginOrRegister(uname, passwd, true, function (err, result) {
- var proxy = result.proxy;
-
- if (err) {
- switch (err) {
- case 'NO_SUCH_USER':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_noSuchUser);
- });
- break;
- case 'INVAL_USER':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_invalUser);
- });
- break;
- case 'INVAL_PASS':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.alert(Messages.login_invalPass);
- });
- break;
- case 'ALREADY_REGISTERED':
- Cryptpad.removeLoadingScreen(function () {
- Cryptpad.confirm(Messages.register_alreadyRegistered, function (yes) {
- if (!yes) { return; }
- proxy.login_name = uname;
-
- if (!proxy[Cryptpad.displayNameKey]) {
- proxy[Cryptpad.displayNameKey] = uname;
- }
- Cryptpad.eraseTempSessionValues();
- logMeIn(result);
- });
- });
- break;
- default: // UNHANDLED ERROR
- Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
- }
- return;
- }
- Cryptpad.eraseTempSessionValues();
- if (shouldImport) {
- sessionStorage.migrateAnonDrive = 1;
- }
-
- proxy.login_name = uname;
- proxy[Cryptpad.displayNameKey] = uname;
- sessionStorage.createReadme = 1;
-
- logMeIn(result);
- });
+ // setTimeout 100ms to remove the keyboard on mobile devices before the loading screen pops up
+ window.setTimeout(function () {
+ Cryptpad.addLoadingScreen(Messages.login_hashing);
+ // We need a setTimeout(cb, 0) otherwise the loading screen is only displayed after hashing the password
+ window.setTimeout(function () {
+ Login.loginOrRegister(uname, passwd, true, function (err, result) {
+ var proxy = result.proxy;
+
+ if (err) {
+ switch (err) {
+ case 'NO_SUCH_USER':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_noSuchUser);
+ });
+ break;
+ case 'INVAL_USER':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_invalUser);
+ });
+ break;
+ case 'INVAL_PASS':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.alert(Messages.login_invalPass);
+ });
+ break;
+ case 'ALREADY_REGISTERED':
+ Cryptpad.removeLoadingScreen(function () {
+ Cryptpad.confirm(Messages.register_alreadyRegistered, function (yes) {
+ if (!yes) { return; }
+ proxy.login_name = uname;
+
+ if (!proxy[Cryptpad.displayNameKey]) {
+ proxy[Cryptpad.displayNameKey] = uname;
+ }
+ Cryptpad.eraseTempSessionValues();
+ logMeIn(result);
+ });
+ });
+ break;
+ default: // UNHANDLED ERROR
+ Cryptpad.errorLoadingScreen(Messages.login_unhandledError);
+ }
+ return;
+ }
+ Cryptpad.eraseTempSessionValues();
+ if (shouldImport) {
+ sessionStorage.migrateAnonDrive = 1;
+ }
+
+ proxy.login_name = uname;
+ proxy[Cryptpad.displayNameKey] = uname;
+ sessionStorage.createReadme = 1;
+
+ logMeIn(result);
+ });
+ }, 0);
+ }, 100);
}, {
ok: Messages.register_writtenPassword,
cancel: Messages.register_cancel,
diff --git a/www/slide/main.js b/www/slide/main.js
index 3b01ae9fd..b5dd26704 100644
--- a/www/slide/main.js
+++ b/www/slide/main.js
@@ -293,34 +293,17 @@ define([
}
/* add a history button */
- var histConfig = {};
- histConfig.onRender = function (val) {
- if (typeof val === "undefined") { return; }
- try {
- var hjson = JSON.parse(val || '{}');
- var remoteDoc = hjson.content;
+ var histConfig = {
+ onLocal: config.onLocal(),
+ onRemote: config.onRemote(),
+ setHistory: setHistory,
+ applyVal: function (val) {
+ var remoteDoc = JSON.parse(val || '{}').content;
editor.setValue(remoteDoc || '');
editor.save();
- } catch (e) {
- // Probably a parse error
- console.error(e);
- }
- };
- histConfig.onClose = function () {
- // Close button clicked
- setHistory(false, true);
- };
- histConfig.onRevert = function () {
- // Revert button clicked
- setHistory(false, false);
- config.onLocal();
- config.onRemote();
- };
- histConfig.onReady = function () {
- // Called when the history is loaded and the UI displayed
- setHistory(true);
+ },
+ $toolbar: $bar
};
- histConfig.$toolbar = $bar;
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
$rightside.append($hist);
@@ -491,11 +474,11 @@ define([
Slide.onChange(function (o, n, l) {
if (n !== null) {
- document.title = APP.title + ' (' + (++n) + '/' + l + ')';
+ document.title = Title.title + ' (' + (++n) + '/' + l + ')';
return;
}
console.log("Exiting presentation mode");
- document.title = APP.title;
+ document.title = Title.title;
});
Cryptpad.removeLoadingScreen();
diff --git a/www/slide/slide.js b/www/slide/slide.js
index c9e6f3dcd..912820390 100644
--- a/www/slide/slide.js
+++ b/www/slide/slide.js
@@ -211,7 +211,10 @@ define([
$(ifrw).focus();
change(null, Slide.index);
if (!isPresentURL()) {
- window.location.hash += '/present';
+ if (window.location.href.slice(-1) !== '/') {
+ window.location.hash += '/';
+ }
+ window.location.hash += 'present';
}
$pad.contents().find('.cryptpad-present-button').hide();
$pad.contents().find('.cryptpad-source-button').show();
@@ -220,7 +223,7 @@ define([
$('.top-bar').hide();
return;
}
- window.location.hash = window.location.hash.replace(/\/present$/, '');
+ window.location.hash = window.location.hash.replace(/\/present$/, '/');
change(Slide.index, null);
$pad.contents().find('.cryptpad-present-button').show();
$pad.contents().find('.cryptpad-source-button').hide();