Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging

pull/1/head
ansuz 8 years ago
commit 84b64da76d

@ -76,7 +76,7 @@
<div id="align-container">
<div id="main-container">
<div id="data" class="hidden">
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
<p class="left" data-localization="main_info"><!-- Collaborate in Confidence. --></p>
</div>
<div id="userForm" class="form-group hidden">

@ -1,50 +0,0 @@
define(['/bower_components/jquery/dist/jquery.min.js'], function() {
var $ = window.jQuery;
var out = {};
var LS_LANG = "CRYPTPAD_LANG";
var getStoredLanguage = function () {
return localStorage.getItem(LS_LANG);
};
var storeLanguage = function (l) {
localStorage.setItem(LS_LANG, l);
};
var getBrowserLanguage = function () {
return navigator.language || navigator.userLanguage;
};
var getLanguage = out.getLanguage = function () {
return getStoredLanguage() || getBrowserLanguage();
};
var main = out.main = function ($select) {
var selector = $select || $('#language-selector');
if (!selector.length) { return; }
var $button = $(selector).find('button .buttonTitle');
// Select the current language in the list
var language = getLanguage();
var option = $(selector).find('[data-value="' + language + '"]');
if ($(option).length) {
$button.text($(option).text());
}
else {
$button.text('English');
}
// Listen for language change
$(selector).find('a.languageValue').on('click', function () {
var newLanguage = $(this).attr('data-value');
storeLanguage(newLanguage);
if (newLanguage !== language) {
window.location.reload();
}
});
};
return out;
});

@ -3,9 +3,8 @@ define([
'/customize/application_config.js',
'/common/cryptpad-common.js',
'/bower_components/lil-uri/uri.min.js',
'/customize/languageSelector.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Messages, Config, Cryptpad, LilUri, LS) {
], function (Messages, Config, Cryptpad, LilUri) {
var $ = window.$;
var APP = window.APP = {

@ -1,70 +1,78 @@
define(['/customize/languageSelector.js',
'/customize/translations/messages.js',
'/customize/translations/messages.es.js',
'/customize/translations/messages.fr.js',
(function () {
var LS_LANG = "CRYPTPAD_LANG";
// 1) additional translation files can be added here...
'/customize/translations/messages.pl.js',
'/customize/translations/messages.de.js',
'/customize/translations/messages.pt-br.js',
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
var language = getLanguage();
// add your module to this map so it gets used
var map = {
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil'
};
'/bower_components/jquery/dist/jquery.min.js'],
var req = ['/customize/translations/messages.js'];
if (language && map[language]) { req.push('/customize/translations/messages.' + language + '.js'); }
req.push('/bower_components/jquery/dist/jquery.min.js');
// 2) name your language module here...
function(LS, Default, Spanish, French, Polish, German, BrPortuguese) {
define(req, function(Default, Language) {
var $ = window.jQuery;
// 3) add your module to this map so it gets used
var map = {
'fr': French,
'es': Spanish,
'pl': Polish,
'de': German,
'pt-br': BrPortuguese,
};
var externalMap = JSON.parse(JSON.stringify(map));
map.en = 'English';
var defaultLanguage = 'en';
var language = LS.getLanguage();
var messages;
if (!language || language === defaultLanguage || language === 'default' || !map[language]) {
if (!Language || !language || language === defaultLanguage || language === 'default' || !map[language]) {
messages = Default;
}
else {
// Add the translated keys to the returned object
messages = $.extend(true, {}, Default, map[language]);
messages = $.extend(true, {}, Default, Language);
}
// messages_languages return the available translations and their name in an object :
// { "en": "English", "fr": "French", ... }
messages._languages = {
'en': Default._languageName
};
for (var l in map) {
messages._languages[l] = map[l]._languageName || l;
}
messages._languages = map;
messages._initSelector = LS.main;
messages._checkTranslationState = function () {
messages._checkTranslationState = function (cb) {
if (typeof(cb) !== "function") { return; }
var missing = [];
Object.keys(map).forEach(function (code) {
var translation = map[code];
var reqs = [];
Object.keys(externalMap).forEach(function (code) {
reqs.push('/customize/translations/messages.' + code + '.js');
});
require(reqs, function () {
var langs = arguments;
Object.keys(externalMap).forEach(function (code, i) {
var translation = langs[i];
Object.keys(Default).forEach(function (k) {
if (/^_/.test(k) || /nitialState$/.test(k)) { return; }
if (!translation[k]) {
var warning = "key [" + k + "] is missing from translation [" + code + "]";
missing.push(warning);
//var warning = "key [" + k + "] is missing from translation [" + code + "]";
//missing.push(warning);
missing.push([code, k, 1]);
}
});
Object.keys(translation).forEach(function (k) {
if (/^_/.test(k) || /nitialState$/.test(k)) { return; }
if (!Default[k]) {
//var warning = "key [" + k + "] from [" + code + "] is not needed anymore and should be removed";
//missing.push(warning);
missing.push([code, k, 0]);
}
});
if (typeof(translation._languageName) !== 'string') {
/*if (typeof(translation._languageName) !== 'string') {
var warning = 'key [_languageName] is missing from translation [' + code + ']';
missing.push(warning);
}
}*/
});
cb(missing);
});
return missing;
};
// Get keys with parameters
@ -76,6 +84,35 @@ define(['/customize/languageSelector.js',
});
};
// Add handler to the language selector
var storeLanguage = function (l) {
localStorage.setItem(LS_LANG, l);
};
messages._initSelector = function ($select) {
var selector = $select || $('#language-selector');
if (!selector.length) { return; }
var $button = $(selector).find('button .buttonTitle');
// Select the current language in the list
var option = $(selector).find('[data-value="' + language + '"]');
if ($(option).length) {
$button.text($(option).text());
}
else {
$button.text('English');
}
// Listen for language change
$(selector).find('a.languageValue').on('click', function () {
var newLanguage = $(this).attr('data-value');
storeLanguage(newLanguage);
if (newLanguage !== language) {
window.location.reload();
}
});
};
var translateText = function (i, e) {
var $el = $(e);
var key = $el.data('localization');
@ -126,4 +163,6 @@ define(['/customize/languageSelector.js',
'{"metadata":{"defaultTitle":"' + messages.driveReadmeTitle + '","title":"' + messages.driveReadmeTitle + '"}}]';
return messages;
});
}());

@ -5,7 +5,7 @@
<div id="align-container">
<div id="main-container">
<div id="data" class="hidden">
<p class="left" data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>
<p class="left" data-localization="main_info"><!-- Collaborate in Confidence. --></p>
</div>
<div id="userForm" class="form-group hidden">

@ -20,63 +20,51 @@ To include your translation in the list, you'll need to add it to `/customize.di
There are comments indicating what to modify in three places:
```javascript
define(['/customize/languageSelector.js',
'/customize/translations/messages.js',
'/customize/translations/messages.es.js',
'/customize/translations/messages.fr.js',
(function () {
var LS_LANG = "CRYPTPAD_LANG";
// 1) additional translation files can be added here...
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
var language = getLanguage();
'/bower_components/jquery/dist/jquery.min.js'],
// 2) name your language module here...
function(LS, Default, Spanish, French) {
var $ = window.jQuery;
// 3) add your module to this map so it gets used
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French"
var map = {
'fr': French,
'es': Spanish,
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil'
};
```
We need to modify these three places to include our file:
We need to modify that map to include our translation:
```javascript
define(['/customize/languageSelector.js',
'/customize/translations/messages.js',
'/customize/translations/messages.es.js',
'/customize/translations/messages.fr.js',
// 1) additional translation files can be added here...
'/customize/translations/messages.pirate.js', // add our module via its path
'/bower_components/jquery/dist/jquery.min.js'],
(function () {
var LS_LANG = "CRYPTPAD_LANG";
// 2) name your language module here...
function(LS, Default, Spanish, French, Pirate) { // name our module 'Pirate' for use as a variable
var $ = window.jQuery;
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
var language = getLanguage();
// 3) add your module to this map so it gets used
// add your module to this map so it gets used
// please use the translated name of your language ("Français" and not "French"
var map = {
'fr': French,
'es': Spanish,
'pirate': Pirate, // add our module to the map of languages
'fr': 'Français',
'es': 'Español',
'pl': 'Polski',
'de': 'Deutsch',
'pt-br': 'Português do Brasil'
'pirate': 'English Pirate', // add our module to the map of languages
};
```
Note that the path to the file is `/customize/translations/`, not `/customize.dist/translations`.
Cryptpad's server is configured to search for files in `/customize/` first.
If a file is not found, it falls back to `/customize.dist/`.
This allows administrators of a Cryptpad installation to override the default behaviour with their own files.
We want translations to be the default behaviour, so we'll place it in `/customize.dist/translations/`, but resolve it via `/customize/translations/`.
The second and third steps are simpler.
Just add your module in a similar fashion to the existing translations, save your changes, and close `/customize.dist/messages.js`.
That's all!
## Actually translating content
Now we can go back to our file, `/customize.dist/translations/messages.pirate.js` and start to add our Pirate-language customizations.
@ -88,9 +76,7 @@ You should see something like:
define(function () {
var out = {};
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
out._languageName = 'English';
out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing";
```
Now you just need to work through this file, updating the strings like so:
@ -99,13 +85,11 @@ Now you just need to work through this file, updating the strings like so:
define(function () {
var out = {};
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
out._languageName = 'Pirate';
out.main_title = "Cryptpad: Knowledge lost at sea while ye scribble with yer mateys";
```
It's important that you modify just the string, and not the variable name which is used to access its content.
For instance, changing `_languageName` to `_language_name` would make the string `'Pirate'` inaccessible to the rest of the codebase.
For instance, changing `main_title` to `mainTitle` would make the translated string inaccessible to the rest of the codebase.
If a key is not found in your translation, the default English version of that key will be used.
This is to make sure that buttons and other interface elements are not empty, but it's obviously not ideal.
@ -119,8 +103,8 @@ Checking frequently will make it easier to know which change caused the error.
Additionally, we advise using the apps and visiting the various pages, to make sure that your translations make sense in context.
When you're happy with your translation file, you can visit http://localhost:3000/assert/ to view Cryptpad's tests.
Among other things, these tests will check to make sure that your translation has an entry for every entry in the default English translation.
When you're happy with your translation file, you can visit http://localhost:3000/assert/translations/ to view Cryptpad's tests.
These tests will check to make sure that your translation has an entry for every entry in the default English translation.
## Getting Help

@ -1,10 +1,6 @@
define(function () {
var out = {};
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
out._languageName = "Français";
out.main_title = "Cryptpad: Éditeur collaboratif en temps réel, zero knowledge";
out.main_slogan = "L'unité est la force, la collaboration est la clé";
@ -15,11 +11,10 @@ define(function () {
out.type.slide = 'Présentation';
out.type.drive = 'Drive';
out.errorBox_errorType_disconnected = 'Connexion perdue';
out.errorBox_errorExplanation_disconnected = [
'La connexion au serveur a été perdue. Vous pouvez essayer de vous reconnecter en rechargeant la page',
'ou vous pouvez revoir votre travail en fermant cette boîte de dialogue.',
].join('');
out.button_newpad = 'Nouveau document texte';
out.button_newcode = 'Nouvelle page de code';
out.button_newpoll = 'Nouveau sondage';
out.button_newslide = 'Nouvelle présentation';
out.common_connectionLost = "<b>Connexion au serveur perdue</b><br>Vous êtes désormais en mode lecture seule jusqu'au retour de la connexion.";
@ -39,8 +34,6 @@ define(function () {
out.yourself = "Vous-même";
out.anonymousUsers = "éditeurs anonymes";
out.anonymousUser = "éditeur anonyme";
out.shareView = "URL de lecture seule";
out.shareEdit = "URL d'édition";
out.users = "Utilisateurs";
out.and = "Et";
out.viewer = "lecteur";
@ -61,20 +54,11 @@ define(function () {
out.exportButtonTitle = 'Exporter ce document vers un fichier local';
out.exportPrompt = 'Comment souhaitez-vous nommer ce fichier ?';
out.back = '&#8656; Retour';
out.backToCryptpad = '⇐ Retour vers Cryptpad';
out.userButton = 'UTILISATEUR';
out.userButtonTitle = "Changer votre nom d'utilisateur";
out.changeNamePrompt = 'Changer votre nom (laisser vide pour rester anonyme) : ';
out.user_rename = "Changer le nom affiché";
out.user_displayName = "Nom affiché";
out.user_accountName = "Nom d'utilisateur";
out.renameButton = 'RENOMMER';
out.renameButtonTitle = 'Changer le titre utilisé par ce document dans la page d\'accueil de Cryptpad';
out.renamePrompt = 'Quel titre souhaitez-vous utiliser pour ce document ?';
out.renameConflict = 'Un autre document existe déjà avec le même titre';
out.clickToEdit = 'Cliquer pour modifier';
out.forgetButton = 'OUBLIER';
@ -82,9 +66,7 @@ define(function () {
out.forgetPrompt = 'Cliquer sur OK supprimera l\'URL de ce document de la mémoire de votre navigateur (localStorage), êtes-vous sûr ?';
out.shareButton = 'Partager';
out.shareButtonTitle = "Copier l'URL dans le presse-papiers";
out.shareSuccess = 'URL copiée dans le presse-papiers';
out.shareFailed = "Échec de la copie de l'URL dans le presse-papiers";
out.newButton = 'Nouveau';
out.newButtonTitle = 'Créer un nouveau document';
@ -100,13 +82,6 @@ define(function () {
out.colorButton = 'COULEUR DU TEXTE';
out.colorButtonTitle = 'Changer la couleur du texte en mode présentation';
out.commitButton = 'VALIDER';
out.getViewButton = 'LECTURE SEULE';
out.getViewButtonTitle = "Obtenir l'adresse d'accès à ce document en lecture seule";
out.readonlyUrl = 'Document en lecture seule';
out.copyReadOnly = "Copier l'URL dans le presse-papiers";
out.openReadOnly = "Ouvrir dans un nouvel onglet";
out.editShare = "Partager l'URL d'édition";
out.editShareTitle = "Copier l'URL d'édition dans le presse-papiers";
out.viewShare = "Partager l'URL de lecture";
@ -123,11 +98,6 @@ define(function () {
out.cancel = "Annuler";
out.cancelButton = 'Annuler (Echap)';
out.loginText = '<p>Votre nom d\'utilisateur et votre mot de passe sont utilisés pour générer une clé unique qui reste inconnue de notre serveur.</p>\n' +
'<p>Faites attention de ne pas oublier vos identifiants puisqu\'ils seront impossible à récupérer.</p>'; //TODO
out.forget = "Oublier";
// Polls
out.poll_title = "Sélecteur de date Zero Knowledge";
@ -135,9 +105,6 @@ define(function () {
out.poll_p_save = "Vos modifications sont mises à jour instantanément, donc vous n'avez jamais besoin de sauver le contenu.";
out.poll_p_encryption = "Tout ce que vous entrez est chiffré donc seules les personnes possédant le lien du sondage y ont accès. Même le serveur ne peut pas voir le contenu.";
out.poll_p_howtouse = "Entrez votre nom dans le champ ci-dessous et cochez les cases lorsque les options vous conviennent.";
out.promptName = "Quel est votre nom ?";
out.wizardButton = 'ASSISTANT';
out.wizardLog = "Cliquez sur le bouton dans le coin supérieur gauche pour retourner au sondage";
@ -158,22 +125,10 @@ define(function () {
out.poll_wizardAddDateButton = "+ Dates";
out.poll_wizardAddTimeButton = "+ Horaires";
out.poll_addUserButton = "+ Utilisateurs";
out.poll_addUserButtonTitle = "Cliquer pour ajouter un utilisateur";
out.poll_addOptionButton = "+ Options";
out.poll_addOptionButtonTitle = "Cliquer pour ajouter une option";
out.poll_addOption = "Indiquer la nouvelle option";
out.poll_optionPlaceholder = "Option";
out.poll_addUser = "Entrer un nom";
out.poll_userPlaceholder = "Votre nom";
out.poll_removeOption = "Êtes-vous sûr de vouloir supprimer cette option ?";
out.poll_removeOptionTitle = "Supprimer la ligne";
out.poll_removeUser = "Êtes-vous sûr de vouloir supprimer cet utilisateur ?";
out.poll_removeUserTitle = "Supprimer la colonne";
out.poll_editOption = "Êtes-vous sûr de vouloir éditer cette option ?";
out.poll_editOptionTitle = "Éditer la ligne";
out.poll_editUser = "Êtes-vous sûr de vouloir éditer les choix de cet utilisateur ?";
out.poll_editUserTitle = "Éditer la colonne";
out.poll_titleHint = "Titre";
out.poll_descriptionHint = "Description";
@ -228,10 +183,6 @@ define(function () {
out.fc_restore = "Restaurer";
out.fc_remove = "Supprimer définitivement";
out.fc_empty = "Vider la corbeille";
out.fc_newpad = "Nouveau pad de texte";
out.fc_newcode = "Nouveau pad de code";
out.fc_newslide = "Nouvelle présentation";
out.fc_newpoll = "Nouveau sondage";
out.fc_prop = "Propriétés";
// fileObject.js (logs)
out.fo_moveUnsortedError = "La liste des éléments non triés ne peut pas contenir de dossiers.";
@ -248,36 +199,13 @@ define(function () {
out.logoutButton = "Déconnexion";
out.settingsButton = "Préférences";
out.login_migrate = "Souhaitez-vous importer les données existantes de votre session anonyme ?";
out.username_label = "Nom d'utilisateur : ";
out.displayname_label = "Nom affiché : ";
out.login_username = "Nom d'utilisateur";
out.login_password = "Mot de passe";
out.login_confirm = "Confirmer votre mot de passe";
out.login_remember = "Se souvenir de moi";
out.login_cancel_prompt = "...ou si vous avez entré le mauvais nom d'utilisateur ou mot de passe, annulez pour essayer à nouveau.";
out.login_registerSuccess = "Inscription réalisée avec succès. Prenez soin de ne pas oublier votre mot de passe !";
out.login_passwordMismatch = "Les deux mots de passe entrés sont différents. Essayez à nouveau.";
out.login_warning = [
'<h1 id="warning">ATTENTION</h1>',
'<p>Cryptpad sauve vos données personnelles dans un document temps-réel chiffré, comme pour tous les autres types de documents temps-réel.</p>',
'<p>Votre nom d\'utilisateur et votre mot de passe ne sont jamais envoyés au serveur de manière non-chiffré.</p>',
'<p>Ainsi, si vous oubliez votre nom d\'utilisateur ou votre mot de passe, il n\'y a absolument rien que nous puissions faire pour retrouver vos informations perdues.</p>',
'<p><strong>Prenez soin de ne surtout pas oublier votre nom d\'utilisateur OU votre mot de passe !</strong></p>',
].join('\n');
out.login_hashing = "Traitement de vos identifiants, cela peut nécessiter quelques instants.";
out.login_no_user = "Il n'y a aucun utilisateur associé au nom et au mot de passe que vous avez entré.";
out.login_confirm_password = "Veuillez taper de nouveau votre mot de passe pour vous inscrire...";
out.loginText = '<p>Votre nom d\'utilisateur et votre mot d epasse sont utilisés pour générer une clé unique qui reste inconnue de notre serveur.</p>\n' +
'<p>Faîtes attention de ne pas perdre vos identifiants, puisqu\'il est impossible de les récupérer</p>';
out.login_hello = 'Bonjour {0},'; // {0} is the username
out.login_helloNoName = 'Bonjour,';
out.login_accessDrive = 'Accédez à votre drive';
@ -317,18 +245,13 @@ define(function () {
"Êtes-vous sûr de vouloir continuer ?<br>" +
"Tapez “<em>I love CryptPad</em>” pour confirmer.";
out.settings_resetDone = "Votre drive est désormais vide!";
out.settings_resetTips = "Astuces et informations dans CryptDrive";
out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive";
out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles.";
// index.html
//out.main_p1 = 'CryptPad est l\'éditeur collaboratif en temps réel <strong>zero knowledge</strong>. Le chiffrement est effectué depuis votre navigateur, ce qui protège les données contre le serveur, le cloud, et la NSA. La clé de chiffrement est stockée dans l\'<a href="https://fr.wikipedia.org/wiki/Identificateur_de_fragment">identifieur de fragment</a> de l\'URL qui n\'est jamais envoyée au serveur mais est accessible depuis javascript, de sorte qu\'en partageant l\'URL, vous donnez l\'accès au pad à ceux qui souhaitent participer.';
out.main_p1 = "<h2>Collaborez avec confiance</h2><br>Développez vos idées en groupe avec des documents partagés; la technologie <strong>Zero Knowledge</strong> sécurise vos données.";
out.main_p2 = 'Ce projet utilise l\'éditeur visuel (WYSIWYG) <a href="http://ckeditor.com/">CKEditor</a>, l\'éditeur de code source <a href="https://codemirror.net/">CodeMirror</a>, et le moteur temps-réel <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a>.';
out.main_howitworks_p1 = 'CryptPad utilise une variante de l\'algorithme d\'<a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> qui est capable de trouver un consensus distribué en utilisant <a href="https://bitcoin.org/bitcoin.pdf">une chaîne de bloc Nakamoto</a>, un outil popularisé par le <a href="https://fr.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. De cette manière, l\'algorithme évite la nécessité d\'utiliser un serveur central pour résoudre les conflits d\'édition de l\'Operational Transformation, et sans ce besoin de résolution des conflits le serveur peut rester ignorant du contenu qui est édité dans le pad.';
out.main_about = 'À propos';
out.main_about_p1 = 'Vous pouvez en apprendre davantage sur notre <a href="/privacy.html" title="">politique de confidentialité</a> et nos <a href="/terms.html">conditions d\'utilisation</a>.';
out.main_about_p2 = 'Si vous avez des questions ou commentaires, vous pouvez <a href="https://twitter.com/cryptpad">nous tweeter</a>, ouvrir une issue sur <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">Github</a>, venir dire bonjour sur IRC (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>), ou <a href="mailto:research@xwiki.com">nous envoyer un email</a>.';
out.main_openFileManager = 'Ouvrir dans un nouvel onglet';
out.main_info = "<h2>Collaborez avec confiance</h2><br>Développez vos idées en groupe avec des documents partagés; la technologie <strong>Zero Knowledge</strong> sécurise vos données.";
out.main_howitworks = 'Comment ça fonctionne';
out.main_zeroKnowledge = 'Zero Knowledge';
@ -354,20 +277,6 @@ define(function () {
out.footer_contact = "Contact";
out.footer_aboutUs = "À propos de nous";
out.table_type = 'Type';
out.table_link = 'Lien';
out.table_created = 'Créé le';
out.table_last = 'Dernier accès';
out.button_newpad = 'Nouveau document texte';
out.button_newcode = 'Nouvelle page de code';
out.button_newpoll = 'Nouveau sondage';
out.button_newslide = 'Nouvelle présentation';
out.form_title = "Tous vos pads, partout où vous allez !";
out.form_username = "Nom d'utilisateur";
out.form_password = "Mot de passe";
out.about = "À propos";
out.privacy = "Vie privée";
out.contact = "Contact";

@ -1,13 +1,8 @@
define(function () {
var out = {};
// translations must set this key for their language to be available in
// the language dropdowns that are shown throughout Cryptpad's interface
// NOTE: translate that name in your language ("Français" and not "French")
out._languageName = 'English';
out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing";
out.main_slogan = "Unity is Strength - Collaboration is Key";
out.main_slogan = "Unity is Strength - Collaboration is Key"; // TODO remove?
out.type = {};
out.type.pad = 'Rich text';
@ -16,11 +11,10 @@ define(function () {
out.type.slide = 'Presentation';
out.type.drive = 'Drive';
out.errorBox_errorType_disconnected = 'Connection Lost';
out.errorBox_errorExplanation_disconnected = [
'Lost connection to server, you may reconnect by reloading the page or review your work ',
'by clicking outside of this box.'
].join('');
out.button_newpad = 'New Rich Text pad';
out.button_newcode = 'New Code pad';
out.button_newpoll = 'New Poll';
out.button_newslide = 'New Presentation';
// NOTE: We want to update the 'common_connectionLost' key.
// Please do not add a new 'updated_common_connectionLostAndInfo' but change directly the value of 'common_connectionLost'
@ -43,8 +37,6 @@ define(function () {
out.yourself = "Yourself";
out.anonymousUsers = "anonymous editors";
out.anonymousUser = "anonymous editor";
out.shareView = "Read-only URL";
out.shareEdit = "Edit URL";
out.users = "Users";
out.and = "And";
out.viewer = "viewer";
@ -65,20 +57,11 @@ define(function () {
out.exportButtonTitle = 'Export this document to a local file';
out.exportPrompt = 'What would you like to name your file?';
out.back = '&#8656; Back';
out.backToCryptpad = '⇐ Back to Cryptpad';
out.userButton = 'USER';
out.userButtonTitle = 'Change your username';
out.changeNamePrompt = 'Change your name (leave empty to be anonymous): ';
out.user_rename = "Change display name";
out.user_displayName = "Display name";
out.user_accountName = "Account name";
out.renameButton = 'RENAME';
out.renameButtonTitle = 'Change the title under which this document is listed on your home page';
out.renamePrompt = 'How would you like to title this pad?';
out.renameConflict = 'Another pad already has that title';
out.clickToEdit = "Click to edit";
out.forgetButton = 'FORGET';
@ -86,9 +69,7 @@ define(function () {
out.forgetPrompt = 'Clicking OK will remove the URL for this pad from localStorage, are you sure?';
out.shareButton = 'Share';
out.shareButtonTitle = "Copy URL to clipboard";
out.shareSuccess = 'Copied URL to clipboard';
out.shareFailed = "Failed to copy URL to clipboard";
out.newButton = 'New';
out.newButtonTitle = 'Create a new document';
@ -96,7 +77,7 @@ define(function () {
out.presentButton = 'PRESENT';
out.presentButtonTitle = "Enter presentation mode";
out.presentSuccess = 'Hit ESC to exit presentation mode';
out.sourceButton = 'VIEW SOURCE';
out.sourceButton = 'VIEW SOURCE'; //TODO remove? hidden behind the present mode
out.sourceButtonTitle = "Leave presentation mode";
out.backgroundButton = 'BACKGROUND COLOR';
@ -104,13 +85,6 @@ define(function () {
out.colorButton = 'TEXT COLOR';
out.colorButtonTitle = 'Change the text color in presentation mode';
out.commitButton = 'COMMIT';
out.getViewButton = 'READ-ONLY URL';
out.getViewButtonTitle = 'Get the read-only URL for this document';
out.readonlyUrl = 'Read only document';
out.copyReadOnly = "Copy URL to clipboard";
out.openReadOnly = "Open in a new tab";
out.editShare = "Share edit URL";
out.editShareTitle = "Copy the edit URL to clipboard";
out.viewShare = "Share view URL";
@ -124,11 +98,9 @@ define(function () {
out.okButton = 'OK (enter)';
out.cancel = "Cancel";
out.cancel = "Cancel"; // Not used?
out.cancelButton = 'Cancel (esc)';
out.forget = "Forget";
// Polls
out.poll_title = "Zero Knowledge Date Picker";
@ -136,9 +108,6 @@ define(function () {
out.poll_p_save = "Your settings are updated instantly, so you never need to save.";
out.poll_p_encryption = "All your input is encrypted so only people who have the link can access it. Even the server cannot see what you change.";
out.poll_p_howtouse = "Enter your name in the input field below and check the box for times when you are available";
out.promptName = "What is you name ?";
out.wizardButton = 'WIZARD';
out.wizardLog = "Click the button in the top left to return to your poll";
@ -159,22 +128,10 @@ define(function () {
out.poll_wizardAddDateButton = "+ Dates";
out.poll_wizardAddTimeButton = "+ Times";
out.poll_addUserButton = "+ Users";
out.poll_addUserButtonTitle = "Click to add a user";
out.poll_addOptionButton = "+ Options";
out.poll_addOptionButtonTitle = "Click to add an option";
out.poll_addOption = "Propose an option";
out.poll_optionPlaceholder = "Option";
out.poll_addUser = "Enter a name";
out.poll_userPlaceholder = "Your name";
out.poll_removeOption = "Are you sure you'd like to remove this option?";
out.poll_removeOptionTitle = "Remove the row";
out.poll_removeUser = "Are you sure you'd like to remove this user?";
out.poll_removeUserTitle = "Remove the column";
out.poll_editOption = "Are you sure you'd like to edit this option?";
out.poll_editOptionTitle = "Edit the row";
out.poll_editUser = "Are you sure you'd like to edit this user?";
out.poll_editUserTitle = "Edit the column";
out.poll_titleHint = "Title";
out.poll_descriptionHint = "Describe your poll, and use the 'publish' button when you're done. Anyone with the link can change the description, but this is discouraged.";
@ -229,10 +186,6 @@ define(function () {
out.fc_restore = "Restore";
out.fc_remove = "Delete permanently";
out.fc_empty = "Empty the trash";
out.fc_newpad = "New text pad";
out.fc_newcode = "New code pad";
out.fc_newslide = "New presentation";
out.fc_newpoll = "New poll";
out.fc_prop = "Properties";
// fileObject.js (logs)
out.fo_moveUnsortedError = "You can't move a folder to the list of unsorted pads";
@ -249,36 +202,13 @@ define(function () {
out.logoutButton = "Log out";
out.settingsButton = "Settings";
out.login_migrate = "Would you like to migrate existing data from your anonymous session?";
out.username_label = "Username: ";
out.displayname_label = "Display name: ";
out.login_username = "Username";
out.login_password = "Password";
out.login_confirm = "Confirm your password";
out.login_remember = "Remember me";
out.login_cancel_prompt = "...or if you may have entered the wrong username or password, cancel to try again.";
out.login_registerSuccess = "registered successfully. Make sure you don't forget your password!";
out.login_passwordMismatch = "The two passwords you entered do not match. Try again";
out.login_warning = [
'<h1 id="warning">WARNING</h1>',
'<p>Cryptpad stores your personal information in an encrypted realtime document, as it does with all other types of realtime documents.</p>',
'<p>Your username and password are never sent to the server in an unencrypted form.</p>',
'<p>As such, if you forget your username or password, there is absolutely nothing that we can do to recover your lost information.</p>',
'<p><strong>Make sure you do not forget your username and password!</strong></p>',
].join('\n');
out.login_hashing = "Hashing your password, this might take some time.";
out.login_no_user = "There is no user associated with the username and password that you entered.";
out.login_confirm_password = "Re-enter your password to register...";
out.loginText = '<p>Your username and password are used to generate a unique key which is never known by our server.</p>\n' +
'<p>Be careful not to forget your credentials, as they are impossible to recover</p>';
out.login_hello = 'Hello {0},'; // {0} is the username
out.login_helloNoName = 'Hello,';
out.login_accessDrive = 'Access your drive';
@ -318,19 +248,13 @@ define(function () {
"Are you sure you want to continue?<br>" +
"Type “<em>I love CryptPad</em>” to confirm.";
out.settings_resetDone = "Your drive is now empty!";
out.settings_resetTips = "Tips in CryptDrive";
out.settings_resetTipsButton = "Reset the available tips in CryptDrive";
out.settings_resetTipsDone = "All the tips are now visible again.";
// index.html
//out.main_p1 = 'CryptPad is the <strong>zero knowledge</strong> realtime collaborative editor. Encryption carried out in your web browser protects the data from the server, the cloud, and the NSA. The secret encryption key is stored in the URL <a href="https://en.wikipedia.org/wiki/Fragment_identifier">fragment identifier</a> which is never sent to the server but is available to javascript so by sharing the URL, you give authorization to others who want to participate.';
//out.main_p1 = "Type quick documents with friends and colleagues.<br>With <strong>Zero Knowledge</strong> technology, the server doesn't know what you're doing.";
out.main_p1 = "<h1>Collaborate in Confidence</h1><br> Grow your ideas together with shared documents while <strong>Zero Knowledge</strong> technology secures your privacy; even from us.";
out.main_p2 = 'This project uses the <a href="http://ckeditor.com/">CKEditor</a> Visual Editor, <a href="https://codemirror.net/">CodeMirror</a>, and the <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a> realtime engine.';
out.main_howitworks_p1 = 'CryptPad uses a variant of the <a href="https://en.wikipedia.org/wiki/Operational_transformation">Operational transformation</a> algorithm which is able to find distributed consensus using a <a href="https://bitcoin.org/bitcoin.pdf">Nakamoto Blockchain</a>, a construct popularized by <a href="https://en.wikipedia.org/wiki/Bitcoin">Bitcoin</a>. This way the algorithm can avoid the need for a central server to resolve Operational Transform Edit Conflicts and without the need for resolving conflicts, the server can be kept unaware of the content which is being edited on the pad.';
out.main_about = 'About';
out.main_about_p1 = 'You can read more about <a href="/about.html">how CryptPad works</a>, our <a href="/privacy.html" title="">privacy policy</a> and <a href="/terms.html">terms of service</a>.';
out.main_about_p2 = 'If you have any questions or comments, you can <a href="https://twitter.com/cryptpad">tweet us</a>, open an issue <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">on github</a>, come say hi on irc (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>), or <a href="mailto:research@xwiki.com">send us an email</a>.';
out.main_openFileManager = 'Open in a new tab';
out.main_info = "<h1>Collaborate in Confidence</h1><br> Grow your ideas together with shared documents while <strong>Zero Knowledge</strong> technology secures your privacy; even from us.";
out.main_howitworks = 'How It Works';
out.main_zeroKnowledge = 'Zero Knowledge';
@ -356,20 +280,6 @@ define(function () {
out.footer_contact = "Contact";
out.footer_aboutUs = "About us";
out.table_type = 'Type';
out.table_link = 'Link';
out.table_created = 'Created';
out.table_last = 'Last Accessed';
out.button_newpad = 'New Rich Text pad';
out.button_newcode = 'New Code pad';
out.button_newpoll = 'New Poll';
out.button_newslide = 'New Presentation';
out.form_title = "All your pads, everywhere!";
out.form_username = "Username";
out.form_password = "Password";
out.about = "About";
out.privacy = "Privacy";
out.contact = "Contact";

@ -142,8 +142,7 @@ define([
});
assert(function () {
var missing = Cryptpad.Messages._checkTranslationState();
var todo = function (missing) {
if (missing.length !== 0) {
missing.forEach(function (msg) {
console.log('* ' + msg);
@ -152,6 +151,9 @@ define([
// No, this is crappy, it's going to cause tests to fail basically all of the time.
//return false;
}
};
Cryptpad.Messages._checkTranslationState(todo);
return true;
}, "expected all translation keys in default language to be present in all translations. See console for details.");

@ -5,12 +5,12 @@ define([
var $ = window.jQuery;
var $body = $('body');
var missing = Cryptpad.Messages._checkTranslationState();
var pre = function (text, opt) {
return $('<pre>', opt).text(text);
};
var todo = function (missing) {
if (missing.length) {
$body.append(pre(missing.map(function (msg) {
return '* ' + msg;
@ -18,4 +18,6 @@ define([
} else {
$body.text('All keys are present in all translations');
}
};
Cryptpad.Messages._checkTranslationState(todo);
});

@ -22,6 +22,7 @@ define([
Cryptpad: Cryptpad,
};
$(function () {
Cryptpad.styleAlerts();
Cryptpad.addLoadingScreen();
@ -30,7 +31,6 @@ define([
return JSONSortify(obj);
};
$(function () {
var toolbar;
var secret = Cryptpad.getSecrets();

@ -875,24 +875,6 @@ define([
}));
}
break;
case 'rename':
button = $('<button>', {
id: 'name-pad',
title: Messages.renameButton + '\n' + Messages.renameButtonTitle,
'class': "fa fa-bookmark cryptpad-rename",
style: 'font:'+size+' FontAwesome'
});
if (data && data.suggestName && callback) {
var suggestName = data.suggestName;
button.click(function() {
var suggestion = suggestName();
common.prompt(Messages.renamePrompt, suggestion, function (title, ev) {
renamePad(title, callback);
});
});
}
break;
case 'forget':
button = $('<button>', {
id: 'cryptpad-forget',
@ -920,18 +902,6 @@ define([
});
}
break;
case 'username':
button = $('<button>', {
title: Messages.userButton + '\n' + Messages.userButtonTitle
}).html('<span class="fa fa-user" style="font-family:FontAwesome;"></span>');
if (data && typeof data.lastName !== "undefined" && callback) {
button.click(function() {
common.prompt(Messages.changeNamePrompt, data.lastName, function (newName) {
callback(newName);
});
});
}
break;
case 'editshare':
button = $('<a>', {
title: Messages.editShareTitle,

@ -29,10 +29,10 @@
<div id="contentContextMenu" class="contextMenu dropdown clearfix" oncontextmenu="return false;">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" href="#" class="newfolder editable dropdown-item" data-localization="fc_newfolder">New folder</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="pad" data-localization="fc_newpad">New pad</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="code" data-localization="fc_newcode">New code</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="slide" data-localization="fc_newslide">New slide</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="poll" data-localization="fc_newpoll">New poll</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="pad" data-localization="button_newpad">New pad</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="code" data-localization="button_newcode">New code</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="slide" data-localization="button_newslide">New slide</a></li>
<li><a tabindex="-1" href="#" class="newdoc own editable dropdown-item" data-type="poll" data-localization="button_newpoll">New poll</a></li>
</ul>
</div>
<div id="defaultContextMenu" class="contextMenu dropdown clearfix" oncontextmenu="return false;">

@ -16,11 +16,12 @@ define([
var $ = window.jQuery;
var saveAs = window.saveAs;
var $iframe = $('#pad-iframe').contents();
var ifrw = $('#pad-iframe')[0].contentWindow;
// Use `$(function () {});` to make sure the html is loaded before doing anything else
$(function () {
var $iframe = $('#pad-iframe').contents();
var ifrw = $('#pad-iframe')[0].contentWindow;
Cryptpad.addLoadingScreen();
var onConnectError = function (info) {
@ -2032,5 +2033,5 @@ define([
}
});
});
});

@ -1,9 +1,8 @@
define([
'/common/cryptpad-common.js',
'/customize/languageSelector.js',
'/common/login.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Cryptpad, LS, Login) {
], function (Cryptpad, Login) {
var $ = window.$;
var APP = window.APP = {

@ -21,6 +21,9 @@ define([
Visible, Notify) {
var $ = window.jQuery;
var saveAs = window.saveAs;
$(function () {
var ifrw = $('#pad-iframe')[0].contentWindow;
var Ckeditor; // to be initialized later...
var DiffDom = window.diffDOM;
@ -814,4 +817,6 @@ define([
};
$(first);
});
});

@ -15,6 +15,8 @@ define([
], function (Config, Messages, TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Renderer, Toolbar, Visible, Notify) {
var $ = window.jQuery;
$(function () {
var unlockHTML = '<i class="fa fa-unlock" aria-hidden="true"></i>';
var lockHTML = '<i class="fa fa-lock" aria-hidden="true"></i>';
var HIDE_INTRODUCTION_TEXT = "hide_poll_text";
@ -786,5 +788,7 @@ define([
onConnectError();
}
});
});
});

@ -39,7 +39,6 @@ define([
} else {
$main.find('#userForm').removeClass('hidden');
}
});
// text and password input fields
var $uname = $('#username');
@ -139,3 +138,4 @@ define([
});
});
});
});

@ -18,6 +18,7 @@
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.0.0",
});
</script>
</head>

@ -43,7 +43,7 @@ define([
var accountName = obj.login_name;
if (!accountName) { return; }
var $label = $('<span>', {'class': 'label'}).text(Messages.login_username_label);
var $label = $('<span>', {'class': 'label'}).text(Messages.user_accountName + ':');
var $name = $('<span>').text(accountName);
$div.append($label).append($name);
@ -54,7 +54,7 @@ define([
var createDisplayNameInput = function (store) {
var obj = store.proxy;
var $div = $('<div>', {'class': 'displayName'});
var $label = $('<label>', {'for' : 'displayName'}).text(Messages.login_displayname_label).appendTo($div);
var $label = $('<label>', {'for' : 'displayName'}).text(Messages.user_displayName).appendTo($div);
$('<br>').appendTo($div);
var $input = $('<input>', {
'type': 'text',
@ -95,7 +95,24 @@ define([
return $div;
};
var createResetTips = function () {
var $div = $('<div>', {'class': 'resetTips'});
var $label = $('<label>', {'for' : 'resetTips'}).text(Messages.settings_resetTips).appendTo($div);
$('<br>').appendTo($div);
var $button = $('<button>', {'id': 'resetTips', 'class': 'btn btn-primary'})
.text(Messages.settings_resetTipsButton).appendTo($div);
$button.click(function () {
Object.keys(localStorage).forEach(function (k) {
if(k.slice(0, 9) === "hide-info") {
delete localStorage[k];
}
});
Cryptpad.alert(Messages.settings_resetTipsDone);
});
return $div;
};
var createBackupDrive = function (store) {
var obj = store.proxy;
var $div = $('<div>', {'class': 'backupDrive'});
@ -155,6 +172,7 @@ define([
APP.$container.append(createTitle());
APP.$container.append(createInfoBlock(obj));
APP.$container.append(createDisplayNameInput(obj));
APP.$container.append(createResetTips());
APP.$container.append(createBackupDrive(obj));
APP.$container.append(createResetDrive(obj));
obj.proxy.on('change', [], refresh);

@ -28,9 +28,7 @@ define([
var SLIDE_BACKCOLOR_ID = "cryptpad-backcolor";
var SLIDE_COLOR_ID = "cryptpad-color";
Cryptpad.styleAlerts();
Cryptpad.addLoadingScreen();
var stringify = function (obj) {
return JSONSortify(obj);
@ -45,6 +43,9 @@ define([
};
$(function () {
Cryptpad.styleAlerts();
Cryptpad.addLoadingScreen();
var ifrw = module.ifrw = $('#pad-iframe')[0].contentWindow;
var toolbar;

Loading…
Cancel
Save