Fix Flash Of Unstyled Content (fouc)

pull/1/head
yflory 8 years ago
parent 046220f239
commit 87abfff66b

@ -10,8 +10,7 @@ define([
var main = function () { var main = function () {
var url = window.location.pathname; var url = window.location.pathname;
var isHtml = /\.html/.test(url) || url === '/' || url === ''; var isHtml = /\.html/.test(url) || url === '/' || url === '';
var isPoll = /\/poll\//.test(url); if (!isHtml) {
if (!isHtml && !isPoll) {
Messages._applyTranslation(); Messages._applyTranslation();
return; return;
} }

@ -146,11 +146,6 @@ define([
if (!Cryptpad.getUserHash()) { if (!Cryptpad.getUserHash()) {
localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); localStorage.FS_hash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
} }
window.patchText = TextPatcher.create({
realtime: realtime,
logging: true,
});
}).on('ready', function () { }).on('ready', function () {
if (!rt.proxy[Cryptpad.storageKey] || !Cryptpad.isArray(rt.proxy[Cryptpad.storageKey])) { if (!rt.proxy[Cryptpad.storageKey] || !Cryptpad.isArray(rt.proxy[Cryptpad.storageKey])) {
var oldStore = Cryptpad.getStore(true); var oldStore = Cryptpad.getStore(true);
@ -171,7 +166,7 @@ define([
} }
return; return;
} }
Cryptpad.alert(Messages.common_connectionLost); //Cryptpad.alert(Messages.common_connectionLost);
}); });
}; };

@ -315,6 +315,37 @@ tr {
font-family: lato, Helvetica, sans-serif; font-family: lato, Helvetica, sans-serif;
font-size: 1.02em; font-size: 1.02em;
} }
#loading {
position: fixed;
z-index: 9999;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
background: #302B28;
text-align: center;
font-size: 1.5em;
}
#loading .loadingContainer {
margin-top: 50vh;
transform: translateY(-50%);
}
#loading .cryptofist {
margin-left: auto;
margin-right: auto;
}
@media screen and (max-height: 450px) {
#loading .cryptofist {
display: none;
}
}
#loading .spinnerContainer {
position: relative;
height: 100px;
}
#loading .spinnerContainer > div {
height: 100px;
}
#main { #main {
width: 70vw; width: 70vw;
margin: auto; margin: auto;

@ -142,6 +142,36 @@ p, pre, td, a, table, tr {
.lato; .lato;
} }
#loading {
position: fixed;
z-index: 9999;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
background: @bg-loading;
text-align: center;
font-size: 1.5em;
.loadingContainer {
margin-top: 50vh;
transform: translateY(-50%);
}
.cryptofist {
margin-left: auto;
margin-right: auto;
@media screen and (max-height: 450px) {
display: none;
}
}
.spinnerContainer {
position: relative;
height: 100px;
> div {
height: 100px;
}
}
}
#main { #main {
width: 70vw; width: 70vw;
margin: auto; margin: auto;

@ -32,3 +32,4 @@
@alertify-input-bg: @base; @alertify-input-bg: @base;
@alertify-input-fg: @fore; @alertify-input-fg: @fore;
@bg-loading: @base;

@ -19,6 +19,10 @@ define(function () {
].join(''); ].join('');
out.common_connectionLost = 'Connexion au serveur perdue'; out.common_connectionLost = 'Connexion au serveur perdue';
out.websocketError = 'Impossible de se connecter au serveur WebSocket...';
out.loading = "Chargement...";
out.error = "Erreur";
out.disconnected = 'Déconnecté'; out.disconnected = 'Déconnecté';
out.synchronizing = 'Synchronisation'; out.synchronizing = 'Synchronisation';
@ -212,6 +216,7 @@ define(function () {
out.fo_existingNameError = "Ce nom est déjà utilisé dans ce répertoire. Veuillez en choisir un autre."; out.fo_existingNameError = "Ce nom est déjà utilisé dans ce répertoire. Veuillez en choisir un autre.";
out.fo_moveFolderToChildError = "Vous ne pouvez pas déplacer un dossier dans un de ses descendants"; out.fo_moveFolderToChildError = "Vous ne pouvez pas déplacer un dossier dans un de ses descendants";
out.fo_unableToRestore = "Impossible de restaurer ce fichier à son emplacement d'origine. Vous pouvez essayer de le déplacer à un nouvel emplacement."; out.fo_unableToRestore = "Impossible de restaurer ce fichier à son emplacement d'origine. Vous pouvez essayer de le déplacer à un nouvel emplacement.";
out.fo_unavailableName = "Un fichier ou dossier avec le même nom existe déjà au nouvel emplacement. Renommez cet élément avant d'essayer à nouveau.";
// index.html // index.html

@ -23,6 +23,9 @@ define(function () {
out.common_connectionLost = 'Server Connection Lost'; out.common_connectionLost = 'Server Connection Lost';
out.websocketError = 'Unable to connect to the websocket server...'; out.websocketError = 'Unable to connect to the websocket server...';
out.loading = "Loading...";
out.error = "Error";
out.disconnected = 'Disconnected'; out.disconnected = 'Disconnected';
out.synchronizing = 'Synchronizing'; out.synchronizing = 'Synchronizing';
out.reconnecting = 'Reconnecting...'; out.reconnecting = 'Reconnecting...';
@ -211,6 +214,7 @@ define(function () {
out.fo_existingNameError = "Name already used in that directory. Please choose another one."; out.fo_existingNameError = "Name already used in that directory. Please choose another one.";
out.fo_moveFolderToChildError = "You can't move a folder into one of its descendants"; out.fo_moveFolderToChildError = "You can't move a folder into one of its descendants";
out.fo_unableToRestore = "Unable to restore that file to its original location. You can try to move it to a new location."; out.fo_unableToRestore = "Unable to restore that file to its original location. You can try to move it to a new location.";
out.fo_unavailableName = "A file or a folder with the same name already exist at the new location. Rename the element and try again.";
// login // login
out.login_login = "log in"; out.login_login = "log in";

@ -21,12 +21,10 @@ define([
var module = window.APP = { var module = window.APP = {
Cryptpad: Cryptpad, Cryptpad: Cryptpad,
spinner: Cryptpad.spinner(document.body),
}; };
Cryptpad.styleAlerts(); Cryptpad.styleAlerts();
Cryptpad.addLoadingScreen();
module.spinner.show();
var ifrw = module.ifrw = $('#pad-iframe')[0].contentWindow; var ifrw = module.ifrw = $('#pad-iframe')[0].contentWindow;
var stringify = function (obj) { var stringify = function (obj) {
@ -43,8 +41,7 @@ define([
} }
var onConnectError = function (info) { var onConnectError = function (info) {
module.spinner.hide(); Cryptpad.errorLoadingScreen(Messages.websocketError);
Cryptpad.alert(Messages.websocketError);
}; };
var andThen = function (CMeditor) { var andThen = function (CMeditor) {
@ -565,7 +562,7 @@ define([
}); });
} }
$(module.spinner.get().el).fadeOut(750); Cryptpad.removeLoadingScreen();
setEditable(true); setEditable(true);
initializing = false; initializing = false;
//Cryptpad.log("Your document is ready"); //Cryptpad.log("Your document is ready");

@ -735,6 +735,26 @@ define([
}); });
}; };
var LOADING = 'loading';
common.addLoadingScreen = function () {
var $loading = $('<div>', {id: LOADING});
var $container = $('<div>', {'class': 'loadingContainer'});
$container.append('<img class="cryptofist" src="/customize/cryptofist_small.png" />');
var $spinner = $('<div>', {'class': 'spinnerContainer'});
loadingSpinner = common.spinner($spinner).show();
var $text = $('<p>').text(Messages.loading);
$container.append($spinner).append($text);
$loading.append($container);
$('body').append($loading);
};
common.removeLoadingScreen = function () {
$('#' + LOADING).fadeOut(750);
};
common.errorLoadingScreen = function (error) {
$('.spinnerContainer').hide();
$('#' + LOADING).find('p').text(error || Messages.error);
};
/* /*
* Saving files * Saving files
*/ */
@ -1066,17 +1086,17 @@ define([
$(parent).append($target); $(parent).append($target);
var opts = { var opts = {
lines: 9, // The number of lines to draw lines: 20, // The number of lines to draw
length: 12, // The length of each line length: 5, // The length of each line
width: 11, // The line thickness width: 2, // The line thickness
radius: 20, // The radius of the inner circle radius: 15, // The radius of the inner circle
scale: 2, // Scales overall size of the spinner scale: 2, // Scales overall size of the spinner
corners: 1, // Corner roundness (0..1) corners: 1, // Corner roundness (0..1)
color: '#777', // #rgb or #rrggbb or array of colors color: '#ddd', // #rgb or #rrggbb or array of colors
opacity: 0.3, // Opacity of the lines opacity: 0.3, // Opacity of the lines
rotate: 31, // The rotation offset rotate: 31, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise direction: 1, // 1: clockwise, -1: counterclockwise
speed: 0.9, // Rounds per second speed: 1, // Rounds per second
trail: 49, // Afterglow percentage trail: 49, // Afterglow percentage
fps: 20, // Frames per second when using setTimeout() as a fallback for CSS fps: 20, // Frames per second when using setTimeout() as a fallback for CSS
zIndex: 2e9, // The z-index (defaults to 2000000000) zIndex: 2e9, // The z-index (defaults to 2000000000)
@ -1085,7 +1105,8 @@ define([
left: '50%', // Left position relative to parent left: '50%', // Left position relative to parent
shadow: false, // Whether to render a shadow shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration hwaccel: false, // Whether to use hardware acceleration
position: 'absolute', // Element positioning position: 'relative', // Element positioning
height: '100px'
}; };
var spinner = new Spinner(opts).spin($target[0]); var spinner = new Spinner(opts).spin($target[0]);

@ -254,7 +254,7 @@ define([
var parentEl = exp.findElement(files, parentPath); var parentEl = exp.findElement(files, parentPath);
if (path.length === 4 && path[0] === TRASH) { if (path.length === 4 && path[0] === TRASH) {
files[TRASH][path[1]].splice(path[2], 1); files[TRASH][path[1]].splice(path[2], 1);
} else if (path[0] === UNSORTED) { } else if (path[0] === UNSORTED) { //TODO || === TEMPLATE
parentEl.splice(key, 1); parentEl.splice(key, 1);
} else { } else {
parentEl[key] = undefined; parentEl[key] = undefined;
@ -264,6 +264,7 @@ define([
}; };
// Find an element in a object following a path, resursively // Find an element in a object following a path, resursively
// NOTE: it is always used with an absolute path and root === files in our code
var findElement = exp.findElement = function (root, pathInput) { var findElement = exp.findElement = function (root, pathInput) {
if (!pathInput) { if (!pathInput) {
error("Invalid path:\n", pathInput, "\nin root\n", root); error("Invalid path:\n", pathInput, "\nin root\n", root);
@ -279,6 +280,7 @@ define([
return findElement(root[key], path); return findElement(root[key], path);
}; };
// Get the object {element: element, path: [path]} from a trash root path
var getTrashElementData = exp.getTrashElementData = function (trashPath) { var getTrashElementData = exp.getTrashElementData = function (trashPath) {
if (!isInTrashRoot) { if (!isInTrashRoot) {
debug("Called getTrashElementData on a element not in trash root: ", trashPath); debug("Called getTrashElementData on a element not in trash root: ", trashPath);
@ -289,6 +291,7 @@ define([
return findElement(files, parentPath); return findElement(files, parentPath);
}; };
// Get data from AllFiles (Cryptpad_RECENTPADS)
var getFileData = exp.getFileData = function (file) { var getFileData = exp.getFileData = function (file) {
if (!file) { return; } if (!file) { return; }
var res; var res;
@ -328,6 +331,7 @@ define([
}; };
// Move to trash // Move to trash
// TODO: rename the function
var removeElement = exp.removeElement = function (path, cb, keepOld) { var removeElement = exp.removeElement = function (path, cb, keepOld) {
if (!path || path.length < 2 || path[0] === TRASH) { if (!path || path.length < 2 || path[0] === TRASH) {
debug("Calling removeElement from a wrong path: ", path); debug("Calling removeElement from a wrong path: ", path);
@ -343,6 +347,7 @@ define([
if (cb) { cb(); } if (cb) { cb(); }
}; };
//TODO add suport for TEMPLATE here
var moveElement = exp.moveElement = function (elementPath, newParentPath, cb, keepOld) { var moveElement = exp.moveElement = function (elementPath, newParentPath, cb, keepOld) {
if (comparePath(elementPath, newParentPath)) { return; } // Nothing to do... if (comparePath(elementPath, newParentPath)) { return; } // Nothing to do...
if (isPathInTrash(newParentPath)) { if (isPathInTrash(newParentPath)) {
@ -353,12 +358,13 @@ define([
var newParent = findElement(files, newParentPath); var newParent = findElement(files, newParentPath);
// Never move a folder in one of its children
if (isFolder(element) && isSubpath(newParentPath, elementPath)) { if (isFolder(element) && isSubpath(newParentPath, elementPath)) {
log(Messages.fo_moveFolderToChildError); log(Messages.fo_moveFolderToChildError);
return; return;
} }
if (isPathInUnsorted(newParentPath)) { if (isPathInUnsorted(newParentPath)) { //TODO || TEMPLATE
if (isFolder(element)) { if (isFolder(element)) {
log(Messages.fo_moveUnsortedError); log(Messages.fo_moveUnsortedError);
return; return;
@ -386,7 +392,7 @@ define([
var newName = !isPathInRoot(elementPath) ? getAvailableName(newParent, name) : name; var newName = !isPathInRoot(elementPath) ? getAvailableName(newParent, name) : name;
if (typeof(newParent[newName]) !== "undefined") { if (typeof(newParent[newName]) !== "undefined") {
log("A file with the same name already exist at the new location. Rename the file and try again."); log(Messages.fo_unavailableName);
return; return;
} }
newParent[newName] = element; newParent[newName] = element;
@ -523,6 +529,7 @@ define([
var emptyTrash = exp.emptyTrash = function (cb) { var emptyTrash = exp.emptyTrash = function (cb) {
files[TRASH] = {}; files[TRASH] = {};
checkDeletedFiles();
if(cb) { cb(); } if(cb) { cb(); }
}; };
@ -592,7 +599,7 @@ define([
var fixFiles = exp.fixFiles = function () { var fixFiles = exp.fixFiles = function () {
// Explore the tree and check that everything is correct: // Explore the tree and check that everything is correct:
// * 'root', 'trash' and 'filesData' exist and are objects // * 'root', 'trash', 'unsorted' and 'filesData' exist and are objects
// * ROOT: Folders are objects, files are href // * ROOT: Folders are objects, files are href
// * TRASH: Trash root contains only arrays, each element of the array is an object {element:.., path:..} // * TRASH: Trash root contains only arrays, each element of the array is an object {element:.., path:..}
// * FILES_DATA: - Data (title, cdate, adte) are stored in filesData. filesData contains only href keys linking to object with title, cdate, adate. // * FILES_DATA: - Data (title, cdate, adte) are stored in filesData. filesData contains only href keys linking to object with title, cdate, adate.
@ -601,10 +608,6 @@ define([
// * UNSORTED: Contains only files (href), and does not contains files that are in ROOT // * UNSORTED: Contains only files (href), and does not contains files that are in ROOT
debug("Cleaning file system..."); debug("Cleaning file system...");
// Create a backup
if (typeof(localStorage.oldFileSystem) === "undefined") {
localStorage.oldFileSystem = '[]';
}
var before = JSON.stringify(files); var before = JSON.stringify(files);
if (typeof(files[ROOT]) !== "object") { debug("ROOT was not an object"); files[ROOT] = {}; } if (typeof(files[ROOT]) !== "object") { debug("ROOT was not an object"); files[ROOT] = {}; }

@ -18,6 +18,11 @@ define([
var $iframe = $('#pad-iframe').contents(); var $iframe = $('#pad-iframe').contents();
var ifrw = $('#pad-iframe')[0].contentWindow; var ifrw = $('#pad-iframe')[0].contentWindow;
Cryptpad.addLoadingScreen();
var onConnectError = function (info) {
Cryptpad.errorLoadingScreen(Messages.websocketError);
};
var APP = window.APP = { var APP = window.APP = {
$bar: $iframe.find('#toolbar'), $bar: $iframe.find('#toolbar'),
editable: false editable: false
@ -48,12 +53,6 @@ define([
console.error.apply(console, arguments); console.error.apply(console, arguments);
}; };
var log = config.log = Cryptpad.log; var log = config.log = Cryptpad.log;
var DEBUG_LS = APP.DEBUG_LS = {
resetLocalStorage : function () {
delete localStorage[LOCALSTORAGE_OPENED];
delete localStorage[LOCALSTORAGE_LAST];
}
};
var getLastOpenedFolder = function () { var getLastOpenedFolder = function () {
var path; var path;
@ -459,6 +458,7 @@ define([
var andThen = function () { var andThen = function () {
filesOp.moveElements(paths, newPath, cb); filesOp.moveElements(paths, newPath, cb);
}; };
// "force" is currently unused but may be configurable by user
if (newPath[0] !== TRASH || force) { if (newPath[0] !== TRASH || force) {
andThen(); andThen();
return; return;
@ -1405,6 +1405,7 @@ define([
pressKey(e.which, false); pressKey(e.which, false);
}); });
$(ifrw).on('keydown', function (e) { $(ifrw).on('keydown', function (e) {
// "Del"
if (e.which === 46) { if (e.which === 46) {
var $selected = $iframe.find('.selected'); var $selected = $iframe.find('.selected');
if (!$selected.length) { return; } if (!$selected.length) { return; }
@ -1552,6 +1553,7 @@ define([
var $backupButton = Cryptpad.createButton('', true); var $backupButton = Cryptpad.createButton('', true);
$backupButton.on('click', function() { $backupButton.on('click', function() {
var url = window.location.origin + window.location.pathname + '#' + editHash; var url = window.location.origin + window.location.pathname + '#' + editHash;
//TODO change text & transalte
Cryptpad.alert("Backup URL for this pad. It is highly recommended that you do not share it with other people.<br>Anybody with that URL can remove all the files in your file manager.<br>" + url); Cryptpad.alert("Backup URL for this pad. It is highly recommended that you do not share it with other people.<br>Anybody with that URL can remove all the files in your file manager.<br>" + url);
}); });
$userBlock.append($backupButton); $userBlock.append($backupButton);
@ -1566,12 +1568,15 @@ define([
proxy[FILES_DATA] = s; proxy[FILES_DATA] = s;
initLocalStorage(); initLocalStorage();
init(proxy); init(proxy);
APP.userList.onChange();
Cryptpad.removeLoadingScreen();
}); });
return; return;
} }
initLocalStorage(); initLocalStorage();
init(proxy); init(proxy);
APP.userList.onChange(); APP.userList.onChange();
Cryptpad.removeLoadingScreen();
}; };
var onDisconnect = function (info) { var onDisconnect = function (info) {
setEditable(false); setEditable(false);
@ -1593,6 +1598,11 @@ define([
onDisconnect(); onDisconnect();
}); });
}); });
Cryptpad.onError(function (info) {
if (info) {
onConnectError();
}
});
}); });

@ -27,6 +27,7 @@ define([
var DiffDom = window.diffDOM; var DiffDom = window.diffDOM;
Cryptpad.styleAlerts(); Cryptpad.styleAlerts();
Cryptpad.addLoadingScreen();
var stringify = function (obj) { var stringify = function (obj) {
return JSONSortify(obj); return JSONSortify(obj);
@ -60,7 +61,6 @@ define([
logFights: true, logFights: true,
fights: [], fights: [],
Cryptpad: Cryptpad, Cryptpad: Cryptpad,
spinner: Cryptpad.spinner(document.body),
}; };
var toolbar; var toolbar;
@ -78,8 +78,7 @@ define([
}; };
var onConnectError = function (info) { var onConnectError = function (info) {
module.spinner.hide(); Cryptpad.errorLoadingScreen(Messages.websocketError);
Cryptpad.alert(Messages.websocketError);
}; };
var andThen = function (Ckeditor) { var andThen = function (Ckeditor) {
@ -140,9 +139,6 @@ define([
$(inner).css({ $(inner).css({
color: '#333', color: '#333',
}); });
$(module.spinner.get().el).fadeOut(750);
} else {
module.spinner.show();
} }
if (!readOnly || !bool) { if (!readOnly || !bool) {
inner.setAttribute('contenteditable', bool); inner.setAttribute('contenteditable', bool);
@ -657,6 +653,7 @@ define([
console.log("Unlocking editor"); console.log("Unlocking editor");
setEditable(true); setEditable(true);
initializing = false; initializing = false;
Cryptpad.removeLoadingScreen();
// Update the toolbar list: // Update the toolbar list:
// Add the current user in the metadata if he has edit rights // Add the current user in the metadata if he has edit rights
if (readOnly) { return; } if (readOnly) { return; }

@ -22,6 +22,11 @@ define([
var secret = Cryptpad.getSecrets(); var secret = Cryptpad.getSecrets();
var readOnly = secret.keys && !secret.keys.editKeyStr; var readOnly = secret.keys && !secret.keys.editKeyStr;
Cryptpad.addLoadingScreen();
var onConnectError = function (info) {
Cryptpad.errorLoadingScreen(Messages.websocketError);
};
var APP = window.APP = { var APP = window.APP = {
Toolbar: Toolbar, Toolbar: Toolbar,
Hyperjson: Hyperjson, Hyperjson: Hyperjson,
@ -566,6 +571,7 @@ define([
} else { } else {
publish(true); publish(true);
} }
Cryptpad.removeLoadingScreen();
// Update the toolbar list: // Update the toolbar list:
// Add the current user in the metadata if he has edit rights // Add the current user in the metadata if he has edit rights
@ -662,11 +668,7 @@ define([
var disconnect = function (info) { var disconnect = function (info) {
//setEditable(false); // TODO //setEditable(false); // TODO
if (info.error) { Cryptpad.alert(Messages.common_connectionLost);
Cryptpad.alert(Messages.websocketError);
return;
}
//Cryptpad.alert(Messages.common_connectionLost); // TODO
}; };
var config = { var config = {
@ -715,5 +717,10 @@ define([
} }
}); });
}); });
Cryptpad.onError(function (info) {
if (info) {
onConnectError();
}
});
}); });

@ -22,7 +22,6 @@ define([
var module = window.APP = { var module = window.APP = {
Cryptpad: Cryptpad, Cryptpad: Cryptpad,
spinner: Cryptpad.spinner(document.body),
TextPatcher: TextPatcher, TextPatcher: TextPatcher,
Slide: Slide, Slide: Slide,
}; };
@ -32,7 +31,7 @@ define([
var SLIDE_COLOR_ID = "cryptpad-color"; var SLIDE_COLOR_ID = "cryptpad-color";
Cryptpad.styleAlerts(); Cryptpad.styleAlerts();
module.spinner.show(); Cryptpad.addLoadingScreen();
var stringify = function (obj) { var stringify = function (obj) {
return JSONSortify(obj); return JSONSortify(obj);
@ -60,8 +59,7 @@ define([
var presentMode = Slide.isPresentURL(); var presentMode = Slide.isPresentURL();
var onConnectError = function (info) { var onConnectError = function (info) {
module.spinner.hide(); Cryptpad.errorLoadingScreen(Messages.websocketError);
Cryptpad.alert(Messages.websocketError);
}; };
var andThen = function (CMeditor) { var andThen = function (CMeditor) {
@ -663,7 +661,7 @@ define([
document.title = APP.title; document.title = APP.title;
}); });
$(module.spinner.get().el).fadeOut(750); Cryptpad.removeLoadingScreen();
setEditable(true); setEditable(true);
initializing = false; initializing = false;
//Cryptpad.log("Your document is ready"); //Cryptpad.log("Your document is ready");

Loading…
Cancel
Save