Merge branch 'soon' into fileManagerMerge

pull/1/head
yflory 8 years ago
commit 9b3719e0ae

@ -3,18 +3,11 @@
<div class="bottom-bar"> <div class="bottom-bar">
<div class="bottom-bar-left"> <div class="bottom-bar-left">
<span class="bottom-bar-language"> <span class="bottom-bar-language">
<select id="language-selector"> <select id="language-selector"></select>
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</span> </span>
<p data-localization="bottom_france"> <p data-localization="bottom_france">
</p> </p>
</div> </div>
<!--
<div class="bottom-bar-center">
<p><a href="https://github.com/xwiki-labs/cryptpad">Fork me on GitHub</a></p>
</div> -->
<div class="bottom-bar-right"> <div class="bottom-bar-right">
<p data-localization="bottom_support"> <p data-localization="bottom_support">
</p> </p>

@ -18,8 +18,17 @@ define([
$.ajax({ $.ajax({
url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html', url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html',
success: function (ret) { success: function (ret) {
//:$('iframe').height('96%'); var $bar = $(ret);
$('body').append(ret); $('body').append($bar);
var $sel = $bar.find('#language-selector');
Object.keys(Messages._languages).forEach(function (code) {
$sel.append($('<option>', {
value: code,
}).text(Messages._languages[code]));
});
LS.main(); LS.main();
Messages._applyTranslation(); Messages._applyTranslation();
} }

@ -3,10 +3,7 @@
<div class="top-bar"> <div class="top-bar">
<div class="bottom-bar-left"> <div class="bottom-bar-left">
<span class="bottom-bar-language"> <span class="bottom-bar-language">
<select id="language-selector"> <select id="language-selector"></select>
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</span> </span>
<p data-localization="header_france" class="big"> <p data-localization="header_france" class="big">
</p> </p>
@ -16,7 +13,8 @@
<p><a id="cryptpad-logo" class="small" href="/" data-localization-title="header_logoTitle"><img src="/customize/cryptofist_mini.png" alt="Cryptpad" class="cryptofist" /></a></p> <p><a id="cryptpad-logo" class="small" href="/" data-localization-title="header_logoTitle"><img src="/customize/cryptofist_mini.png" alt="Cryptpad" class="cryptofist" /></a></p>
</div> </div>
<div class="bottom-bar-right"> <div class="bottom-bar-right">
<p data-localization="header_xwiki" class="small"> <p class="small">
<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer"><img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>
<p data-localization="header_support" class="big"> <p data-localization="header_support" class="big">
</p> </p>
</div> </div>

@ -4,7 +4,7 @@ define(function() {
/* Select the buttons displayed on the main page to create new collaborative sessions /* Select the buttons displayed on the main page to create new collaborative sessions
* Existing types : pad, code, poll, slide * Existing types : pad, code, poll, slide
*/ */
config.availablePadTypes = ['pad', 'code', 'poll', 'slide']; config.availablePadTypes = ['pad', 'code', 'slide', 'poll'];
return config; return config;
}); });

@ -40,7 +40,7 @@
<div id="main"> <div id="main">
<center> <center>
<img class="imgcenter cryptofist" src="/customize/cryptofist_small.png" /> <img class="imgcenter cryptofist" src="/customize/cryptofist_small.png" />
<h1>Unity is Strength - Collaboration is Key</h1> <h1 data-localization="main_slogan">Unity is Strength - Collaboration is Key</h1>
</center> </center>
<p data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p> <p data-localization="main_p1"><!-- Zero Knowledge collaborative realtime editor. Protected from the NSA. --></p>

@ -28,8 +28,9 @@ define([
var forgetPad = Cryptpad.forgetPad; var forgetPad = Cryptpad.forgetPad;
var displayCreateButtons = function () { var displayCreateButtons = function () {
var $parent = $('#buttons');
Config.availablePadTypes.forEach(function (el) { Config.availablePadTypes.forEach(function (el) {
$('#create-' + el).show(); $('#create-' + el).detach().appendTo($parent).show();
}); });
}; };

@ -1,11 +1,20 @@
define(['/customize/languageSelector.js', define(['/customize/languageSelector.js',
'/customize/translations/messages.js', '/customize/translations/messages.js',
'/customize/translations/messages.es.js',
'/customize/translations/messages.fr.js', '/customize/translations/messages.fr.js',
'/bower_components/jquery/dist/jquery.min.js'], function(LS, Default, French) {
// 1) additional translation files can be added here...
'/bower_components/jquery/dist/jquery.min.js'],
// 2) name your language module here...
function(LS, Default, Spanish, French) {
var $ = window.jQuery; var $ = window.jQuery;
// 3) add your module to this map so it gets used
var map = { var map = {
'fr': French 'fr': French,
'es': Spanish,
}; };
var defaultLanguage = 'en'; var defaultLanguage = 'en';
@ -32,6 +41,24 @@ define(['/customize/languageSelector.js',
} }
messages._initSelector = LS.main; messages._initSelector = LS.main;
messages._checkTranslationState = function () {
var missing = [];
Object.keys(map).forEach(function (code) {
var translation = map[code];
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);
}
});
if (typeof(translation._languageName) !== 'string') {
var warning = 'key [_languageName] is missing from translation [' + code + ']';
missing.push(warning);
}
});
return missing;
};
// Get keys with parameters // Get keys with parameters
messages._getKey = function (key, argArray) { messages._getKey = function (key, argArray) {

@ -0,0 +1,129 @@
# Adding Translations
To illustrate the process of translating, this guide will make an english-pirate translation of Cryptpad.
We'll assume that you have a work locally-installed, properly functioning installation of Cryptpad.
If you don't have Cryptpad installed locally, start by following the steps in the main readme.
## Getting started
Once everything is working, copy the default (English) source file (`/customize.dist/translations/messages.js`) to a file named according to your language's [ISO 639-1 Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes), like `/customize.dist/translations/messages.fr.js`.
There is no ISO 639-1 language code for _English-pirate_, so we'll just call it `messages.pirate.js`.
```Bash
cd /customize.dist/translations/
cp messages.js messages.pirate.js
```
## Including your translation
To include your translation in the list, you'll need to add it to `/customize.dist/messages.js`.
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',
// 1) additional translation files can be added here...
'/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
var map = {
'fr': French,
'es': Spanish,
};
```
We need to modify these three places to include our file:
```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'],
// 2) name your language module here...
function(LS, Default, Spanish, French, Pirate) { // name our module 'Pirate' for use as a variable
var $ = window.jQuery;
// 3) add your module to this map so it gets used
var map = {
'fr': French,
'es': Spanish,
'pirate': 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.
Open the translation file you created in `/customize.dist/translations/`.
You should see something like:
```javascript
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';
```
Now you just need to work through this file, updating the strings like so:
```javascript
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';
```
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.
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.
## Verifying Your Translations
It's advisable to save your translation file frequently, and reload Cryptpad in your browser to check that there are no errors in your translation file.
If there are any errors in your code, the file will fail to parse, and the page will no load correctly.
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.
## Getting Help
If you have any issues, reach out via any of the methods listed in the readme under **Contacting Us**.
We're happy to help.

@ -0,0 +1,244 @@
define(function () {
var out = {};
out._languageName = 'Español';
out.main_title = "Cryptpad: Zero Knowledge, Editor Colaborativo en Tiempo Real";
out.main_slogan = "La unidad es la fuerza - la colaboración es la clave";
out.type = {};
out.type.pad = 'Pad';
out.type.code = 'Código';
out.type.poll = 'Encuesta';
out.type.slide = 'Presentación';
out.errorBox_errorType_disconnected = 'Conexión perdida';
out.errorBox_errorExplanation_disconnected = [
'Se perdio la conexion con el servidor, tu puedes reconectarte actualizando la pagina o revisando tu trabajo ',
'haciendo click por fuera de este cuadro.'
].join('');
out.common_connectionLost = 'Conexión perdida con el servidor';
out.disconnected = "Desconectado";
out.synchronizing = "Sincronización";
out.reconnecting = "Reconectando";
out.lag = "Retraso";
out.readOnly = 'Solo lectura';
out.anonymous = 'Anónimo';
out.yourself = "tú mismo";
out.anonymousUsers = "usuarios anónimos";
out.anonymousUser = "usuario anónimo";
out.shareView = "URL de sólo lectura";
out.shareEdit = "Editar URL";
out.users = "Usuarios";
out.and = "y";
out.viewer = "espectador";
out.viewers = "espectadores";
out.editor = "editor";
out.editors = "editores";
out.editingAlone = 'Editar solo';
out.editingWithOneOtherPerson = 'Editar con otra persona';
out.editingWith = 'Editar con ';
out.otherPeople = 'Otras personas';
out.disconnected = 'Desconectado';
out.synchronizing = 'Sincronizando';
out.reconnecting = 'Reconectando...';
out.lag = 'Retraso';
out.readonly = 'Solo lectura';
out.nobodyIsEditing = 'Nadie está editando';
out.onePersonIsEditing = 'Una personas está editando';
out.peopleAreEditing = '{0} personas están editando';
out.oneViewer = '1 visualizando';
out.viewers = '{0} están visualizando';
out.anonymous = "Actualmente eres anónimo";
out.greenLight = "Todo esta trabajando bién";
out.orangeLight = "Tu conexion es lenta y podria impactar en el desempeño de tu experiencia";
out.redLight = "¡Has sido desconectado de la sesión! ";
out.importButton = 'IMPORTAR';
out.importButtonTitle = 'Importar un documento de tus archivos locales';
out.exportButton = 'EXPORTAR';
out.exportButtonTitle = 'Exportar este documento a un archivo local';
out.exportPrompt = '¿Como te gustaria nombra tu archivo ?';
out.back = '&#8656; Atras';
out.backToCryptpad = '⇐ Atras a Cryptpad';
out.userButton = 'USUARIO';
out.userButtonTitle = 'Cambiar tu nombre de usuario';
out.changeNamePrompt = 'Cambiar tu nombre: ';
out.renameButton = 'RENOMBRAR';
out.renameButtonTitle = 'Cambiar el titulo del documento listado en tu pagina de inicio';
out.renamePrompt = 'Como titularias este noja?';
out.renameConflict = 'Otra nota tiene ya ese titulo';
out.clickToEdit = "Haz click para editar";
out.forgetButton = 'OLVIDAR';
out.forgetButtonTitle = 'Eliminar este documento de la lista en la pagina de inicio';
out.forgetPrompt = 'Presiona OK, removera la URL para esta nota desde el almacenamiento local, ¿Esta seguro?';
out.shareButton = 'COMPARTIR';
out.shareButtonTitle = "Copiar URL al portapapeles";
out.shareSuccess = '¡URL Copiada al portapapeles!';
out.shareFailed = "Fallo al copiar URL al portapapeles";
out.presentButton = 'PRESENTAR';
out.presentButtonTitle = "Ingresar en modo presentación";
out.presentSuccess = 'ESC para salir del modo presentación';
out.sourceButton = 'VER CÓDIGO FUENTE';
out.sourceButtonTitle = "Abandonar modo presentación";
out.backgroundButton = 'COLOR DE FONDO';
out.backgroundButtonTitle = 'Cambiar el color de fondo en el modo presentación';
out.colorButton = 'COLOR DE TEXTO';
out.colorButtonTitle = 'Cambiar el color de texto en el modo presentación';
out.commitButton = 'COMMIT';
out.getViewButton = 'URL SOLO-LECTURA';
out.getViewButtonTitle = 'Obtener URL de solo lectura para este documento';
out.readonlyUrl = 'Documento de solo lectura';
out.copyReadOnly = "Copiar URL al portapapeles";
out.openReadOnly = "Abrir en nueva pestaña";
// TODO VERIFY
out.editShare = "URL de edición compartida";
out.editShareTitle = "Copiar la URL de edición al portapapeles";
out.viewShare = "Compartir vista URL";
out.viewShareTitle = "Copiar la URL de solo lectura al portapapeles";
out.viewOpen = "Ver en nueva pestaña";
out.viewOpenTitle = "Abrir el documento en modo de sólo lectura en una nueva pestaña";
out.notifyJoined = "{0} se ha unido a la sesión de colaboración";
out.notifyRenamed = "{0} ahora se conoce como {1}";
out.notifyLeft = "{0} ha dejado la sesión de colaboración";
out.disconnectAlert = '¡Conexión de Red perdida!';
out.tryIt = '¡PROBARLO!';
out.recentPads = 'Tus notas recientes (están almacenadas en el navegador)';
out.okButton = 'OK (enter)';
out.cancelButton = 'Cancelar (esc)';
out.loginText = '<p>Tu nombre de usuario y password son usados para generar una llave unica que es desconocida por nuestro servidor.</p>\n' +
'<p>Se cuidados no olvides tus credenciales, son imposibles de recuperar</p>';
out.forget = "Olvidar";
// Polls
out.poll_title = "Zero Knowledge selector de fecha";
out.poll_subtitle = "Zero Knowledge, agenda en <em>tiempo real</em> ";
out.poll_p_save = "Tus configuraciones son actualizadas instantaneamente, no es necesario guardar cambios.";
out.poll_p_encryption = "Todos los datos de entrada son cifrados, solo las personas que posee el link tiene acceso. Incluso desde el servidor no puede ver tus cambios.";
out.poll_p_howtouse = "Ingresa tu nombre en el campo de entrada en la parte inferior y verificalo";
out.promptName = "¿ Cual es tu nombre ?";
out.wizardButton = 'ASISTENTE';
out.wizardLog = "Presiona el boton en la parte superior izquierda para regresar a la encuesta";
out.wizardTitle = "Utiliza el asistente para crear tu encuesta";
out.wizardConfirm = "¿Estas realmente seguro de agregar estas opciones a tu encuesta?";
out.poll_closeWizardButton = "Cerrar el asistente";
out.poll_closeWizardButtonTitle = "Cerrar el asistente";
out.poll_wizardComputeButton = "Computar opciones";
out.poll_wizardClearButton = "Limpiar tabla";
out.poll_wizardDescription = "Automaticamente crear un number de opciones ingresando cualquier numero de fechas y segmentos de tiempo";
out.poll_wizardAddDateButton = "+ Fechas";
out.poll_wizardAddTimeButton = "+ Horas";
out.poll_addUserButton = "+ Usuarios";
out.poll_addUserButtonTitle = "Click para adicionar usuario";
out.poll_addOptionButton = "+ Opciones";
out.poll_addOptionButtonTitle = "Click para adicionar una opción";
out.poll_addOption = "Proponer una opción";
out.poll_optionPlaceholder = "Opción";
out.poll_addUser = "Ingresar un nombre";
out.poll_userPlaceholder = "Tu nombre";
out.poll_removeOption = "¿Seguro que te gustaria eliminar esta opción?";
out.poll_removeOptionTitle = "Eliminar la fila";
out.poll_removeUser = "¿Seguro que te gustaria eliminar este usuario?";
out.poll_removeUserTitle = "Eliminar la columna";
out.poll_editOption = "¿Seguro que te gustaria editar esta opción?";
out.poll_editOptionTitle = "Editar la fila";
out.poll_editUser = "¿Seguro que te gustaria editar este usuario?";
out.poll_editUserTitle = "Editar la columna";
out.poll_titleHint = "Titulo";
out.poll_descriptionHint = "Descripción";
// index.html
out.main_p1 = 'CryptPad es un editor en tiempo <strong>zero knowledge</strong>. El cifrado es llevado acabo en tu navegador protegiendo los datos de, sistemas en la nube, and la NSA. La clave cifrado privada es almacenada en la URL <a href="https://en.wikipedia.org/wiki/Fragment_identifier">fragment identifier</a> lo cual no es nunca enviado al servidor pero esta disponible para el javascript compartiendo la URL, tu autorizas a otros quienes desean participar.';
out.main_p2 = 'Este proyecto usa <a href="http://ckeditor.com/">CKEditor</a> un editor de texto, <a href="https://codemirror.net/">CodeMirror</a>, y <a href="https://github.com/xwiki-contrib/chainpad">ChainPad</a> un motor de tiempo real.';
out.main_howitworks = '¿Como Funciona?';
out.main_howitworks_p1 = "CryptPad utiliza una variante del algoritmo de <a href='https://en.wikipedia.org/wiki/Operational_transformation'>transformación Operacional</a> que es capaz de encontrar el consenso distribuido usando un <a href='https://bitcoin.org/bitcoin.pdf'>Nakamoto Blockchain</a>, una construcción popularizada por <a href='https://en.wikipedia.org/wiki/Bitcoin'>Bitcoin</a> . De esta manera el algoritmo puede evitar la necesidad de un servidor central para resolver Conflictos de Edición de Transformación Operacional y sin necesidad de resolver conflictos, el servidor puede mantenerse inconsciente del contenido que se está editando en el pad.";
out.main_about = 'Acerca de';
out.main_about_p1 = 'Tu puedes leer mas acerca de nuestra <a href="/privacy.html" title="">politica de privacidad</a> y <a href="/terms.html">terminos de servicio</a>.';
out.main_about_p2 = 'Si tu tienes preguntas o comentarios, tu puedes <a href="https://twitter.com/cryptpad">tweetearnos </a>,o abrir un issue <a href="https://github.com/xwiki-labs/cryptpad/issues/" title="our issue tracker">en github</a>, ven y di hola a nuestro canal de irc (<a href="http://webchat.freenode.net?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7" title="freenode webchat">irc.freenode.net</a>), o <a href="mailto:research@xwiki.com">envianos un email</a>.';
out.table_type = 'Tipo';
out.table_link = 'Link';
out.table_created = 'Creado';
out.table_last = 'Ultimo Acceso';
out.button_newpad = 'CREAR NUEVA NOTA DE TEXTO ENRIQUECIDO';
out.button_newcode = 'CREAR NUEVA NOTA DE CÓDIGO';
out.button_newpoll = 'CREAR NUEVA ENCUESTA';
out.button_newslide = 'CREAR NUEVA PRESENTACIÓN';
// privacy.html
out.policy_title = 'Cryptpad Política de privacidad';
out.policy_whatweknow = 'Que sabemos sobre tí';
out.policy_whatweknow_p1 = 'Como una aplicación que esta hospedada en la red, Cryptpad tiene acceso a los metadatos expuestos por el protocolo HTTP. Esto incluye tu direccion IP, y otros headers HTTP que puede ser usados para identificar particularmente tu navegador. Tu puedes comprar la informacion que comparte tu navegador visitando <a target="_blank" rel="noopener noreferrer" href="https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending" title="Que headers HTTP esta compartiendo mi navegador">WhatIsMyBrowser.com</a>.';
out.policy_whatweknow_p2 = 'Nosotros usamos <a href="https://piwik.org/" target="_blank" rel="noopener noreferrer" title="open source analytics platform">Piwik</a>, an open source analytics platform, to learn more about our users. Piwik tells us about how you found Cryptpad, via direct entry, through a search engine, or via a referral from another web service like Reddit or Twitter. We also learn when you visit, what links you click while on our informational pages, and how long you stay on a particular page.';
out.policy_whatweknow_p3 = 'Estas herramientas de estadística son usadas solamente para informacion local . Nosotros no recolectamos cualquier informacion sobre el uso de nuestro zero-knowledge application.';
out.policy_howweuse = 'Como nosotros usamos lo que aprendemos';
out.policy_howweuse_p1 = 'Nosotros usamos esta informacion para tomar mejores decisiones como promover y promocionar Cryptpad, para evaluar cual de nuestros esfuerzos pasados han sido exitosos. La informacion sobre tu ubicacion nos permite conocer si nosotros debemos considerar mejor soporte para otros idiomas diferentes al ingles.';
out.policy_howweuse_p2 = "La informacion sobre tu navegador (si es un sistema operativo de escritorio o movil) nos ayuda a tomar medidads en las caracteristicas que debemos priorizar y mejorar. Nuestro equipo de desarrollo es pequeño, intentamos hacer elecciones que beneficien la mayoria de los usuarios' experiencia como sea posible.";
out.policy_whatwetell = 'Lo que nosotros le decimos a otros sobre tí';
out.policy_whatwetell_p1 = 'No suministramos información a terceros, ni la que usted nos proporciona a nosotros a menos de ser obligados legalmente a hacerlo.';
out.policy_links = 'Links a Otros sitios';
out.policy_links_p1 = 'Este sitio contiene links a otros sitios, incluyendo algunos producidos por otras organizaciones. Nosotros no nos responsabilisamos por el tratamiento, privacidad de los datos y contenido de sitios externos. Como regla general, los links externos son abiertos una nueva pestaña del navegador, para hacerlo claro tu estas abandonando Cryptpad.fr.';
out.policy_ads = 'Anuncio';
out.policy_ads_p1 = 'Nosotros no mostramos anuncios online, pensamos que podemos linkear a las personas que financian nuestra investigación.';
out.policy_choices = 'Eleciones que tu tienes';
out.policy_choices_open = 'Nuestro código es open source, Entonces tu siempre tienes la opcion crear tu propia estancia de Cryptpad.';
out.policy_choices_vpn = 'Si tu deseas usar nuestra estancia, pero no deseas exponer tu dirección IP, tu puedes proteger tu dirección IP utilizando <a href="https://www.torproject.org/projects/torbrowser.html.en" title="downloads from the Tor project" target="_blank" rel="noopener noreferrer">Tor browser bundle</a>, o una <a href="https://riseup.net/en/vpn" title="VPNs provided by Riseup" target="_blank" rel="noopener noreferrer">VPN</a>.';
out.policy_choices_ads = 'If usted desea blockear rastreadores, y plataformas similares puedes utilizar herramientas como <a href="https://www.eff.org/privacybadger" title="download privacy badger" target="_blank" rel="noopener noreferrer">Privacy Badger</a>.';
// terms.html
out.tos_title = "Cryptpad Términos de Servicio";
out.tos_legal = "Porfavor no seas malicioso, abusivo o realices prácticas ilegales.";
out.tos_availability = "Nosotros esperamos que encuentres este servicio util, pero nuestra disponibilidad o desempeño no pueden ser garantizados. Por favor exporta tus datos regularmente.";
out.tos_e2ee = "Cryptpad Los documentos pueden ser leidos o modificados para alguien puede ser invitado o por el contrario obtener un fragmento del documento. Nosotros recomendamos que tu uses cifrado punto a punto(e2ee) para compartir URLs, no asumimos ninguna responsabilidad en el evento de que existan fugas de URLs.";
out.tos_logs = "Los metadatos entregados por el navegador a el servidor pueden ser logueados y almacenados para propuestas de mantener el servicio.";
out.tos_3rdparties = "Nosotros no proveemos datos individualizados a terceros a menos que sea requerido por la ley.";
// BottomBar.html
out.bottom_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">Made with <img class="bottom-bar-heart" src="/customize/heart.png" /> en <img class="bottom-bar-fr" src="/customize/fr.png" /></a>';
out.bottom_support = '<a href="http://labs.xwiki.com/" title="XWiki Labs" target="_blank" rel="noopener noreferrer">An <img src="/customize/logo-xwiki2.png" alt="XWiki SAS" class="bottom-bar-xwiki"/> Labs Project </a> with the support of <a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
// Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">With <img class="bottom-bar-heart" src="/customize/heart.png" /> from <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> by <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferre-r"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Ir a la pagina principal';
return out;
});

@ -4,6 +4,7 @@ define(function () {
out._languageName = "Français"; out._languageName = "Français";
out.main_title = "Cryptpad: Editeur collaboratif en temps réel, zero knowledge"; out.main_title = "Cryptpad: Editeur collaboratif en temps réel, zero knowledge";
out.main_slogan = "L'unité est la force, la collaboration est la clé";
out.type = {}; out.type = {};
out.type.pad = 'Pad'; out.type.pad = 'Pad';
@ -206,7 +207,7 @@ define(function () {
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 = '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_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_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 = 'Comment ça fonctionne'; out.main_howitworks = 'Comment ça fonctionne';
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 une chaîne de bloc Nakamoto, 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_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 = 'À 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_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_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>.';
@ -259,7 +260,6 @@ define(function () {
// Header.html // Header.html
out.header_france = '<a href="http://www.xwiki.com/fr" target="_blank" rel="noopener noreferrer">Fait avec <img class="bottom-bar-heart" src="/customize/heart.png" /> en <img class="bottom-bar-fr" title="France" alt="France" src="/customize/fr.png" /> par <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>'; out.header_france = '<a href="http://www.xwiki.com/fr" target="_blank" rel="noopener noreferrer">Fait avec <img class="bottom-bar-heart" src="/customize/heart.png" /> en <img class="bottom-bar-fr" title="France" alt="France" src="/customize/fr.png" /> par <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_xwiki = '<a href="http://www.xwiki.com/fr" target="_blank" rel="noopener noreferrer"><img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>'; out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = "Aller vers la page d'accueil"; out.header_logoTitle = "Aller vers la page d'accueil";

@ -1,9 +1,12 @@
define(function () { define(function () {
var out = {}; 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._languageName = 'English';
out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing"; out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing";
out.main_slogan = "Unity is Strength - Collaboration is Key";
out.type = {}; out.type = {};
out.type.pad = 'Pad'; out.type.pad = 'Pad';
@ -206,7 +209,7 @@ define(function () {
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 = '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_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_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 = 'How It Works'; out.main_howitworks = 'How It Works';
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 Nakamoto Blockchain, 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_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 = 'About';
out.main_about_p1 = 'You can read more about our <a href="/privacy.html" title="">privacy policy</a> and <a href="/terms.html">terms of service</a>.'; out.main_about_p1 = 'You can read more about our <a href="/privacy.html" title="">privacy policy</a> and <a href="/terms.html">terms of service</a>.';
@ -260,7 +263,10 @@ define(function () {
// Header.html // Header.html
out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">With <img class="bottom-bar-heart" src="/customize/heart.png" /> from <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> by <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>'; out.header_france = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer">With <img class="bottom-bar-heart" src="/customize/heart.png" /> from <img class="bottom-bar-fr" src="/customize/fr.png" title="France" alt="France"/> by <img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_xwiki = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer"><img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
// TODO Hardcode cause YOLO
//out.header_xwiki = '<a href="http://www.xwiki.com/" target="_blank" rel="noopener noreferrer"><img src="/customize/logo-xwiki.png" alt="XWiki SAS" class="bottom-bar-xwiki"/></a>';
out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>'; out.header_support = '<a href="http://ng.open-paas.org/" title="OpenPaaS::ng" target="_blank" rel="noopener noreferrer"> <img src="/customize/openpaasng.png" alt="OpenPaaS-ng" class="bottom-bar-openpaas" /></a>';
out.header_logoTitle = 'Go to the main page'; out.header_logoTitle = 'Go to the main page';

@ -101,6 +101,21 @@ the battery out of your computer before it spawns Agent Smith.
Still there are other low-lives in the world so using CryptPad over HTTPS is probably a good idea. Still there are other low-lives in the world so using CryptPad over HTTPS is probably a good idea.
## Translations
We'd like to make it easy for more people to use encryption in their routine activities.
As such, we've tried to make language-specific parts of Cryptpad translatable. If you're
able to translate Cryptpad's interface, and would like to help, please contact us!
You can also see [our translation guide](/customize.dist/translations/README.md).
## Contacting Us
You can reach members of the Cryptpad development team on [twitter](https://twitter.com/cryptpad),
via our [github issue tracker](https://github.com/xwiki-labs/cryptpad/issues/), on the
[freenode](http://webchat.freenode.net/?channels=%23cryptpad&uio=MT1mYWxzZSY5PXRydWUmMTE9Mjg3JjE1PXRydWUe7)
irc network, or by [email](mailto:research@xwiki.com).
## Contributing ## Contributing
We love Open Source and we love contribution. It is our intent to keep this project available We love Open Source and we love contribution. It is our intent to keep this project available

@ -4,7 +4,8 @@ define([
'/bower_components/hyperjson/hyperjson.js', '/bower_components/hyperjson/hyperjson.js',
'/bower_components/textpatcher/TextPatcher.amd.js', '/bower_components/textpatcher/TextPatcher.amd.js',
'json.sortify', 'json.sortify',
], function (jQuery, Hyperjson, TextPatcher, Sortify) { '/common/cryptpad-common.js',
], function (jQuery, Hyperjson, TextPatcher, Sortify, Cryptpad) {
var $ = window.jQuery; var $ = window.jQuery;
window.Hyperjson = Hyperjson; window.Hyperjson = Hyperjson;
window.TextPatcher = TextPatcher; window.TextPatcher = TextPatcher;
@ -140,6 +141,19 @@ define([
strungJSON(orig); strungJSON(orig);
}); });
assert(function () {
var missing = Cryptpad.Messages._checkTranslationState();
if (missing.length !== 0) {
missing.forEach(function (msg) {
console.log('* ' + msg);
});
return false;
}
return true;
}, "expected all translation keys in default language to be present in all translations. See console for details.");
var swap = function (str, dict) { var swap = function (str, dict) {
return str.replace(/\{\{(.*?)\}\}/g, function (all, key) { return str.replace(/\{\{(.*?)\}\}/g, function (all, key) {
return typeof dict[key] !== 'undefined'? dict[key] : all; return typeof dict[key] !== 'undefined'? dict[key] : all;

@ -253,18 +253,21 @@ define([
var clike = /^\s*(\/\*|\/\/)(.*)?(\*\/)*$/; var clike = /^\s*(\/\*|\/\/)(.*)?(\*\/)*$/;
if (clike.test(line)) { if (clike.test(line)) {
line.replace(clike, function (a, one, two) { line.replace(clike, function (a, one, two) {
if (!(two && two.replace)) { return; }
text = two.replace(/\*\/\s*$/, '').trim(); text = two.replace(/\*\/\s*$/, '').trim();
}); });
return true; return true;
} }
// TODO make one more pass for multiline comments
}); });
return text.trim(); return text.trim();
}; };
var suggestName = function () { var suggestName = function (fallback) {
if (document.title === defaultName) { if (document.title === defaultName) {
return getHeadingText() || ""; return getHeadingText() || fallback || "";
} else { } else {
return document.title || getHeadingText() || defaultName; return document.title || getHeadingText() || defaultName;
} }
@ -275,7 +278,7 @@ define([
var ext = Modes.extensionOf(module.highlightMode); var ext = Modes.extensionOf(module.highlightMode);
var title = Cryptpad.fixFileName(suggestName()) + ext; var title = Cryptpad.fixFileName(suggestName('cryptpad')) + (ext || '.txt');
Cryptpad.prompt(Messages.exportPrompt, title, function (filename) { Cryptpad.prompt(Messages.exportPrompt, title, function (filename) {
if (filename === null) { return; } if (filename === null) { return; }
@ -495,9 +498,7 @@ define([
} }
// set the hash // set the hash
if (!readOnly) { if (!readOnly) { Cryptpad.replaceHash(editHash); }
window.location.hash = editHash;
}
Cryptpad.getPadTitle(function (err, title) { Cryptpad.getPadTitle(function (err, title) {
if (err) { if (err) {

@ -28,6 +28,7 @@ define([
var common = { var common = {
User: User, User: User,
Messages: Messages,
}; };
var store; var store;
var fsStore; var fsStore;
@ -238,6 +239,14 @@ define([
return secret; return secret;
}; };
var replaceHash = common.replaceHash = function (hash) {
if (window.history && window.history.replaceState) {
if (!/^#/.test(hash)) { hash = '#' + hash; }
return void window.history.replaceState({}, window.document.title, hash);
}
window.location.hash = hash;
};
var storageKey = common.storageKey = 'CryptPad_RECENTPADS'; var storageKey = common.storageKey = 'CryptPad_RECENTPADS';
/* /*

@ -35,8 +35,23 @@ define([
window.Toolbar = Toolbar; window.Toolbar = Toolbar;
window.Hyperjson = Hyperjson; window.Hyperjson = Hyperjson;
var slice = function (coll) {
return Array.prototype.slice.call(coll);
};
var removeListeners = function (root) {
slice(root.attributes).map(function (attr) {
if (/^on/.test(attr.name)) {
root.attributes.removeNamedItem(attr.name);
}
});
slice(root.children).forEach(removeListeners);
};
var hjsonToDom = function (H) { var hjsonToDom = function (H) {
return Hyperjson.toDOM(H); //callOn(H, Hyperscript); var dom = Hyperjson.toDOM(H);
removeListeners(dom);
return dom;
}; };
var module = window.REALTIME_MODULE = window.APP = { var module = window.REALTIME_MODULE = window.APP = {
@ -321,9 +336,9 @@ define([
})) { return text; } })) { return text; }
}; };
var suggestName = function () { var suggestName = function (fallback) {
if (document.title === defaultName) { if (document.title === defaultName) {
return getHeadingText() || ""; return getHeadingText() || fallback || "";
} else { } else {
return document.title || getHeadingText() || defaultName; return document.title || getHeadingText() || defaultName;
} }
@ -510,7 +525,7 @@ define([
var exportFile = function () { var exportFile = function () {
var html = getHTML(); var html = getHTML();
var suggestion = suggestName(); var suggestion = suggestName('cryptpad-document');
Cryptpad.prompt(Messages.exportPrompt, Cryptpad.prompt(Messages.exportPrompt,
Cryptpad.fixFileName(suggestion) + '.html', function (filename) { Cryptpad.fixFileName(suggestion) + '.html', function (filename) {
if (!(typeof(filename) === 'string' && filename)) { return; } if (!(typeof(filename) === 'string' && filename)) { return; }
@ -601,9 +616,7 @@ define([
} }
// set the hash // set the hash
if (!readOnly) { if (!readOnly) { Cryptpad.replaceHash(editHash); }
window.location.hash = editHash;
}
Cryptpad.getPadTitle(function (err, title) { Cryptpad.getPadTitle(function (err, title) {
if (err) { if (err) {

@ -72,6 +72,23 @@ define([
}); });
}; };
var getLastName = module.getLastName = function (cb) {
Cryptpad.getAttribute('username', function (err, userName) {
cb(err, userName || '');
});
};
var setName = module.setName = function (uname, cb) {
if (typeof(uname) !== 'string') {
return void cb(new Error('expected string'));
}
uname = Cryptpad.fixHTML(uname.trim()).slice(0, 32);
Cryptpad.setAttribute('username', uname, function (err, data) {
if (err) { return void cb(err); }
cb(void 0, uname);
});
};
module.Wizard = Wizard; module.Wizard = Wizard;
// special UI elements // special UI elements
@ -320,12 +337,19 @@ define([
}; };
var scrollDown = module.scrollDown = function (px) { var scrollDown = module.scrollDown = function (px) {
if (module.scrolling) { return; }
module.scrolling = true;
var top = $(window).scrollTop() + px + 'px'; var top = $(window).scrollTop() + px + 'px';
$('html, body').animate({ $('html, body').animate({
scrollTop: top, scrollTop: top,
}, { }, {
duration: 200, duration: 200,
easing: 'swing', easing: 'swing',
complete: function () {
module.scrolling = false;
}
}); });
}; };
@ -397,7 +421,10 @@ define([
addIfAbsent(proxy.table.rowsOrder, id); addIfAbsent(proxy.table.rowsOrder, id);
var $row = table.addRow($wrapper, Checkbox, id); var $row = table.addRow($wrapper, Checkbox, id);
scrollDown($row.height());
if (module.ready) {
scrollDown($row.height());
}
return $option; return $option;
}; };
@ -408,7 +435,7 @@ define([
var msg = Messages.poll_addUser; var msg = Messages.poll_addUser;
Cryptpad.prompt(msg, "", function (name) { Cryptpad.prompt(msg, "", function (name) {
if (name === null) { return; } if (!(name && name.trim())) { return; }
makeUser(module.rt.proxy, id, name).val(name); makeUser(module.rt.proxy, id, name).val(name);
makeUserEditable(id, true).focus(); makeUserEditable(id, true).focus();
}); });
@ -439,7 +466,7 @@ define([
var id = rowuid(); var id = rowuid();
makeOption(proxy, id, text).val(text); makeOption(proxy, id, text).val(text);
}); });
//console.log(options); Wizard.hide();
}); });
}); });
@ -755,14 +782,16 @@ define([
})); }));
} }
/*
if (!readOnly && module.viewHash) { if (!readOnly && module.viewHash) {
/* add a 'links' button */ /* add a 'links' button
var $links = Cryptpad.createButton('readonly', true, {viewHash: module.viewHash}) var $links = Cryptpad.createButton('readonly', true, {viewHash: module.viewHash})
.text(Messages.getViewButton) .text(Messages.getViewButton)
.removeAttr('style') .removeAttr('style')
.attr('class', 'action button readonly'); .attr('class', 'action button readonly');
$toolbar.append($links); $toolbar.append($links);
} }
*/
/* Import/Export buttons */ /* Import/Export buttons */
/* /*
@ -815,7 +844,11 @@ define([
setEditable(true); setEditable(true);
return;
// shortcircuiting before all of this code since it's not quite the
// behaviour we want, and it's a bit of work to make it Do The Right Thing
/*
if (First) { if (First) {
// assume the first user to the poll wants to be the administrator... // assume the first user to the poll wants to be the administrator...
// TODO prompt them with questions to set up their poll... // TODO prompt them with questions to set up their poll...
@ -830,40 +863,34 @@ define([
module.activeColumn = ''; module.activeColumn = '';
var promptForName = function () { var promptForName = function () {
// HERE
Cryptpad.prompt(Messages.promptName, "", function (name, ev) {
if (name === null) {
name = '';
}
if (!module.isEditable) { return; } var followUp = function (name) {
if (!name) { return; }
var id = module.activeColumn = coluid(); var id = module.activeColumn = coluid();
Cryptpad.setPadAttribute('column', id, function (err) { Cryptpad.setPadAttribute('column', id, function (err) {
if (err) { if (err) { return void console.error("Couldn't remember your column id"); }
console.error("Couldn't remember your column id");
return;
}
console.log(id);
makeUser(module.rt.proxy, id, name).focus().val(name); makeUser(module.rt.proxy, id, name).focus().val(name);
makeUserEditable(id, true); makeUserEditable(id, true);
}); });
};
getLastName(function (err, uname) {
if (!uname) {
return void Cryptpad.prompt(Messages.promptName, "", function (name, ev) {
if (!(name || module.isEditable)) { return; }
followUp(name);
});
}
followUp(uname);
}); });
}; };
if (column === null) { if (column === null) { return void promptForName(); }
//console.log("Looks like you're new to this poll, why don't you make a column");
promptForName();
return;
}
// column might be defined, but that column might have been deleted... // column might be defined, but that column might have been deleted...
if (proxy.table.colsOrder.indexOf(column) === -1) { if (proxy.table.colsOrder.indexOf(column) === -1) { return void promptForName(); }
promptForName(); });*/
return;
}
});
}; };
var config = { var config = {
@ -889,9 +916,7 @@ define([
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys); editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
} }
// set the hash // set the hash
if (!readOnly) { if (!readOnly) { Cryptpad.replaceHash(editHash); }
window.location.hash = editHash;
}
module.patchText = TextPatcher.create({ module.patchText = TextPatcher.create({
realtime: realtime, realtime: realtime,

@ -585,7 +585,7 @@ define([
// set the hash // set the hash
if (!window.location.hash || window.location.hash === '#') { if (!window.location.hash || window.location.hash === '#') {
window.location.hash = editHash; Cryptpad.replaceHash(editHash);
} }
Cryptpad.getPadTitle(function (err, title) { Cryptpad.getPadTitle(function (err, title) {

@ -45,7 +45,7 @@ define([
var unsafeTag = function (info) { var unsafeTag = function (info) {
if (['addAttribute', 'modifyAttribute'].indexOf(info.diff.action) !== -1) { if (['addAttribute', 'modifyAttribute'].indexOf(info.diff.action) !== -1) {
if (/^on/.test(info.diff.name)) { if (/^on/.test(info.diff.name)) {
console.log("Rejecting forbidden element attribute with name", info.diff.element.nodeName); console.log("Rejecting forbidden element attribute with name", info.diff.name);
return true; return true;
} }
} }
@ -91,12 +91,28 @@ define([
return patch; return patch;
}; };
var slice = function (coll) {
return Array.prototype.slice.call(coll);
};
/* remove listeners from the DOM */
var removeListeners = function (root) {
slice(root.attributes).map(function (attr) {
if (/^on/.test(attr.name)) {
root.attributes.removeNamedItem(attr.name);
}
});
// all the way down
slice(root.children).forEach(removeListeners);
};
var draw = Slide.draw = function (i) { var draw = Slide.draw = function (i) {
console.log("Trying to draw slide #%s", i); console.log("Trying to draw slide #%s", i);
if (typeof(Slide.content[i]) !== 'string') { return; } if (typeof(Slide.content[i]) !== 'string') { return; }
var c = Slide.content[i]; var c = Slide.content[i];
var Dom = domFromHTML('<div id="content">' + Marked(c) + '</div>'); var Dom = domFromHTML('<div id="content">' + Marked(c) + '</div>');
removeListeners(Dom.body);
var patch = makeDiff(domFromHTML($content[0].outerHTML), Dom); var patch = makeDiff(domFromHTML($content[0].outerHTML), Dom);
if (typeof(patch) === 'string') { if (typeof(patch) === 'string') {

Loading…
Cancel
Save