diff --git a/customize.dist/DecorateToolbar.js b/customize.dist/DecorateToolbar.js index d6f77ea30..6ec6eac89 100644 --- a/customize.dist/DecorateToolbar.js +++ b/customize.dist/DecorateToolbar.js @@ -10,6 +10,11 @@ define([ var main = function () { var url = window.location.pathname; var isHtml = /\.html/.test(url) || url === '/' || url === ''; + var isPoll = /\/poll\//.test(url); + if (!isHtml && !isPoll) { + Messages._applyTranslation(); + return; + } $.ajax({ url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html', success: function (ret) { diff --git a/customize.dist/languageSelector.js b/customize.dist/languageSelector.js index af949a813..f857680b3 100644 --- a/customize.dist/languageSelector.js +++ b/customize.dist/languageSelector.js @@ -20,8 +20,8 @@ define(['/bower_components/jquery/dist/jquery.min.js'], function() { return getStoredLanguage() || getBrowserLanguage(); }; - var main = out.main = function () { - var selector = $('#language-selector'); + var main = out.main = function ($select) { + var selector = $select || $('#language-selector'); if (!selector.length) { return; } // Select the current language in the list diff --git a/customize.dist/messages.js b/customize.dist/messages.js index 1801fc84d..f1062ada3 100644 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -22,6 +22,17 @@ define(['/customize/languageSelector.js', messages = $.extend(true, {}, Default, map[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._initSelector = LS.main; + // Get keys with parameters messages._getKey = function (key, argArray) { if (!messages[key]) { return '?'; } diff --git a/customize.dist/src/toolbar.less b/customize.dist/src/toolbar.less index 9832fc0a9..d8f7b6a6c 100644 --- a/customize.dist/src/toolbar.less +++ b/customize.dist/src/toolbar.less @@ -14,8 +14,8 @@ .unselectable; - color: #666; - font-weight: bold; + font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif; + color: #000; display: inline-block; width: 100%; z-index: 9001; @@ -33,13 +33,13 @@ color: #000; } &.cryptpad-lag { - float: right; + float: left; line-height: 26px; - margin: 2px 0px 2px 4px; + margin: 2px 0px; } } - button, .rightside-element { + button, select, .rightside-element { height: 26px; padding-right: 5px; padding-left: 5px; @@ -108,34 +108,125 @@ .cryptpad-toolbar-top { display: block; text-align: center; + height: 32px; + position: relative; + @media screen and (max-width: 400px) { + height: 67px; + } .cryptpad-title { - text-align: center; + .title, .pencilIcon { + font-size: 1.5em; + vertical-align: middle; + line-height: 32px; + } + .pencilIcon { + display: none; + &:hover { + color: #999; + } + span { + cursor: pointer; + } + } + &:not(input):hover { + .editable { + border: 1px solid #888; + border-radius: 2px 0px 0px 2px; + background: white; + padding: 5px; + border-collapse: collapse; + } + .pencilIcon { + cursor: pointer; + border: 1px solid #888; + border-radius: 0px 2px 2px 0px; + background: white; + padding: 5px; + display: inline; + margin-left: -1px; + border-collapse: collapse; + } + } input { + font-size: 1.5em; + vertical-align: middle; + height: 100%; + box-sizing: border-box; border: 1px solid black; background: #fff; cursor: auto; width: 300px; - padding: 5px; - -webkit-touch-callout: text; - -webkit-user-select: text; - -khtml-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; - &:focus { - -webkit-touch-callout: text; - -webkit-user-select: text; - -khtml-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; + padding: 0px 5px; + } + } + .cryptpad-link { + position: absolute; + left: 0px; + height: 32px; + @media screen and (max-width: 400px) { + top: 35px; + } + @media screen and (min-width: 401px) { + top: 0px; + } + + a.cryptpad-logo { + cursor: pointer; + height: 32px; + padding: 0px 5px; + text-decoration: none; + color: inherit; + &:hover { + span { + text-decoration: underline; + } + } + img { + vertical-align: middle; + height: 32px; + cursor: pointer; } + span { + font-size: 1.5em; + margin-left: 5px; + vertical-align: middle; + cursor: pointer; + } + } + .big { + @media screen and (max-width: 400px) { + display: none; + } + @media screen and (min-width: 401px) { + display: inline-block; + } + } + .small { + @media screen and (max-width: 400px) { + display: inline-block; + } + @media screen and (min-width: 401px) { + display: none; + } + } + } + .cryptpad-user { + position: absolute; + right: 0; + @media screen and (max-width: 400px) { + top: 3em; + } + @media screen and (min-width: 401px) { + top: 0px; } } } .cryptpad-toolbar-leftside { float: left; margin-bottom: -1px; + .cryptpad-user-list { + float: right; + } .cryptpad-dropdown-container { position: relative; display: inline-block; @@ -158,10 +249,7 @@ white-space: normal; &.cryptpad-dropdown-users { text-align:baseline; - .yourself { - font-style: italic; - } - .anonymous { + .yourself, .anonymous, .viewer { font-style: italic; } } @@ -188,7 +276,6 @@ } .cryptpad-toolbar-rightside { text-align: right; - margin-right: 30px; //float: right; } .cryptpad-spinner { @@ -200,7 +287,7 @@ font-size: 20px; } .cryptpad-readonly { - margin-right: 20px; + margin-right: 5px; font-weight: bold; text-transform: uppercase; } diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index 9cbde4f5d..cfde957a3 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -14,8 +14,8 @@ -moz-user-select: none; -ms-user-select: none; user-select: none; - color: #666; - font-weight: bold; + font: normal normal normal 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif; + color: #000; display: inline-block; width: 100%; z-index: 9001; @@ -33,11 +33,12 @@ color: #000; } .cryptpad-toolbar div.cryptpad-lag { - float: right; + float: left; line-height: 26px; - margin: 2px 0px 2px 4px; + margin: 2px 0px; } .cryptpad-toolbar button, +.cryptpad-toolbar select, .cryptpad-toolbar .rightside-element { height: 26px; padding-right: 5px; @@ -104,35 +105,134 @@ .cryptpad-toolbar-top { display: block; text-align: center; + height: 32px; + position: relative; } -.cryptpad-toolbar-top .cryptpad-title { - text-align: center; +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top { + height: 67px; + } +} +.cryptpad-toolbar-top .cryptpad-title .title, +.cryptpad-toolbar-top .cryptpad-title .pencilIcon { + font-size: 1.5em; + vertical-align: middle; + line-height: 32px; +} +.cryptpad-toolbar-top .cryptpad-title .pencilIcon { + display: none; +} +.cryptpad-toolbar-top .cryptpad-title .pencilIcon:hover { + color: #999; +} +.cryptpad-toolbar-top .cryptpad-title .pencilIcon span { + cursor: pointer; +} +.cryptpad-toolbar-top .cryptpad-title:not(input):hover .editable { + border: 1px solid #888; + border-radius: 2px 0px 0px 2px; + background: white; + padding: 5px; + border-collapse: collapse; +} +.cryptpad-toolbar-top .cryptpad-title:not(input):hover .pencilIcon { + cursor: pointer; + border: 1px solid #888; + border-radius: 0px 2px 2px 0px; + background: white; + padding: 5px; + display: inline; + margin-left: -1px; + border-collapse: collapse; } .cryptpad-toolbar-top .cryptpad-title input { + font-size: 1.5em; + vertical-align: middle; + height: 100%; + box-sizing: border-box; border: 1px solid black; background: #fff; cursor: auto; width: 300px; - padding: 5px; - -webkit-touch-callout: text; - -webkit-user-select: text; - -khtml-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; -} -.cryptpad-toolbar-top .cryptpad-title input:focus { - -webkit-touch-callout: text; - -webkit-user-select: text; - -khtml-user-select: text; - -moz-user-select: text; - -ms-user-select: text; - user-select: text; + padding: 0px 5px; +} +.cryptpad-toolbar-top .cryptpad-link { + position: absolute; + left: 0px; + height: 32px; +} +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top .cryptpad-link { + top: 35px; + } +} +@media screen and (min-width: 401px) { + .cryptpad-toolbar-top .cryptpad-link { + top: 0px; + } +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo { + cursor: pointer; + height: 32px; + padding: 0px 5px; + text-decoration: none; + color: inherit; +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo:hover span { + text-decoration: underline; +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo img { + vertical-align: middle; + height: 32px; + cursor: pointer; +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo span { + font-size: 1.5em; + margin-left: 5px; + vertical-align: middle; + cursor: pointer; +} +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top .cryptpad-link .big { + display: none; + } +} +@media screen and (min-width: 401px) { + .cryptpad-toolbar-top .cryptpad-link .big { + display: inline-block; + } +} +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top .cryptpad-link .small { + display: inline-block; + } +} +@media screen and (min-width: 401px) { + .cryptpad-toolbar-top .cryptpad-link .small { + display: none; + } +} +.cryptpad-toolbar-top .cryptpad-user { + position: absolute; + right: 0; +} +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top .cryptpad-user { + top: 3em; + } +} +@media screen and (min-width: 401px) { + .cryptpad-toolbar-top .cryptpad-user { + top: 0px; + } } .cryptpad-toolbar-leftside { float: left; margin-bottom: -1px; } +.cryptpad-toolbar-leftside .cryptpad-user-list { + float: right; +} .cryptpad-toolbar-leftside .cryptpad-dropdown-container { position: relative; display: inline-block; @@ -159,10 +259,9 @@ .cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users { text-align: baseline; } -.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .yourself { - font-style: italic; -} -.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .anonymous { +.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .yourself, +.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .anonymous, +.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .viewer { font-style: italic; } .cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p h2 { @@ -184,7 +283,6 @@ } .cryptpad-toolbar-rightside { text-align: right; - margin-right: 30px; } .cryptpad-spinner { float: left; @@ -195,7 +293,7 @@ font-size: 20px; } .cryptpad-readonly { - margin-right: 20px; + margin-right: 5px; font-weight: bold; text-transform: uppercase; } diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 57f50a33a..03c3a59b4 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -1,6 +1,8 @@ define(function () { var out = {}; + out._languageName = "Français"; + out.main_title = "Cryptpad: Editeur collaboratif en temps réel, zero knowledge"; out.type = {}; @@ -26,8 +28,14 @@ define(function () { out.yourself = "Vous-même"; out.anonymousUsers = "utilisateurs anonymes"; out.anonymousUser = "utilisateur anonyme"; - out.share = "Partage"; + out.shareView = "URL de lecture seule"; + out.shareEdit = "URL d'édition"; out.users = "Utilisateurs"; + out.and = "Et"; + out.viewer = "lecteur"; + out.viewers = "lecteurs"; + out.editor = "éditeur"; + out.editors = "éditeurs"; out.greenLight = "Tout fonctionne bien"; out.orangeLight = "Votre connexion est lente, ce qui réduit la qualité de l'éditeur"; @@ -51,12 +59,13 @@ define(function () { 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'; out.forgetButtonTitle = 'Enlever ce document de la liste en page d\'accueil'; 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.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"; @@ -79,15 +88,17 @@ define(function () { out.readonlyUrl = 'Document en lecture seule'; out.copyReadOnly = "Copier l'URL dans le presse-papiers"; out.openReadOnly = "Ouvrir dans un nouvel onglet"; - out.editing = "éditeur(s)"; - out.viewing = "lecteur(s)"; - out.editShare = "Partager l'URL"; + 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"; out.viewShareTitle = "Copier l'URL d'accès en lecture seule dans le presse-papiers"; out.viewOpen = "Voir dans un nouvel onglet"; out.viewOpenTitle = "Ouvrir le document en lecture seule dans un nouvel onglet"; + out.notifyJoined = "{0} a rejoint la session collaborative"; + out.notifyRenamed = "{0} a changé son nom en {1}"; + out.notifyLeft = "{0} a quitté la session collaborative"; + out.disconnectAlert = 'Perte de la connexion au réseau !'; out.tryIt = 'Essayez-le !'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 51c8f73a7..dd3b9c623 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -1,6 +1,8 @@ define(function () { var out = {}; + out._languageName = 'English'; + out.main_title = "Cryptpad: Zero Knowledge, Collaborative Real Time Editing"; out.type = {}; @@ -26,8 +28,14 @@ define(function () { out.yourself = "Yourself"; out.anonymousUsers = "anonymous users"; out.anonymousUser = "anonymous user"; - out.share = "Share"; + out.shareView = "Read-only URL"; + out.shareEdit = "Edit URL"; out.users = "Users"; + out.and = "And"; + out.viewer = "viewer"; + out.viewers = "viewers"; + out.editor = "editor"; + out.editors = "editors"; out.greenLight = "Everything is working fine"; out.orangeLight = "Your slow connection may impact your experience"; @@ -51,12 +59,13 @@ define(function () { 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'; out.forgetButtonTitle = 'Remove this document from your home page listings'; out.forgetPrompt = 'Clicking OK will remove the URL for this pad from localStorage, are you sure?'; - out.shareButton = 'SHARE'; + out.shareButton = 'Share'; out.shareButtonTitle = "Copy URL to clipboard"; out.shareSuccess = 'Copied URL to clipboard'; out.shareFailed = "Failed to copy URL to clipboard"; @@ -79,15 +88,17 @@ define(function () { out.readonlyUrl = 'Read only document'; out.copyReadOnly = "Copy URL to clipboard"; out.openReadOnly = "Open in a new tab"; - out.editing = "editing"; - out.viewing = "viewing"; - out.editShare = "Share"; + out.editShare = "Share edit URL"; out.editShareTitle = "Copy the edit URL to clipboard"; out.viewShare = "Share view URL"; out.viewShareTitle = "Copy the read-only URL to clipboard"; out.viewOpen = "View in new tab"; out.viewOpenTitle = "Open the document in read-only mode in a new tab"; + out.notifyJoined = "{0} has joined the collaborative session"; + out.notifyRenamed = "{0} is now known as {1}"; + out.notifyLeft = "{0} has left the collaborative session"; + out.disconnectAlert = 'Network connection lost!'; out.tryIt = 'Try it out!'; diff --git a/www/code/index.html b/www/code/index.html index bdef6b6f4..9b7c92d88 100644 --- a/www/code/index.html +++ b/www/code/index.html @@ -21,7 +21,7 @@ } #iframe-container { position: fixed; - top: 2.6em; + top: 0px; bottom: 0px; right: 0px; left: 0px; diff --git a/www/code/main.js b/www/code/main.js index 586910ac0..cf9864eb1 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -45,10 +45,13 @@ define([ var andThen = function (CMeditor) { var CodeMirror = module.CodeMirror = CMeditor; CodeMirror.modeURL = "/bower_components/codemirror/mode/%N/%N.js"; - var $pad = $('#pad-iframe'); var $textarea = $pad.contents().find('#editor1'); + var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); + var parsedHash = Cryptpad.parsePadUrl(window.location.href); + var defaultName = Cryptpad.getDefaultName(parsedHash); + var editor = module.editor = CMeditor.fromTextArea($textarea[0], { lineNumbers: true, lineWrapping: true, @@ -112,21 +115,22 @@ define([ editor.setOption('readOnly', !bool); }; - var userList = module.userList = {}; // List of pretty name of all users (mapped with their server ID) - var toolbarList; // List of users still connected to the channel (server IDs) - var addToUserList = function(data) { + var userData = module.userData = {}; // List of pretty name of all users (mapped with their server ID) + var userList; // List of users still connected to the channel (server IDs) + var addToUserData = function(data) { var users = module.users; + for (var attrname in data) { userData[attrname] = data[attrname]; } + if (users && users.length) { - for (var userKey in userList) { + for (var userKey in userData) { if (users.indexOf(userKey) === -1) { - delete userList[userKey]; + delete userData[userKey]; } } } - for (var attrname in data) { userList[attrname] = data[attrname]; } - if(toolbarList && typeof toolbarList.onChange === "function") { - toolbarList.onChange(userList); + if(userList && typeof userList.onChange === "function") { + userList.onChange(userData); } }; @@ -161,27 +165,30 @@ define([ var initializing = true; + var stringifyInner = function (textValue) { + var obj = { + content: textValue, + metadata: { + users: userData, + defaultTitle: defaultName + } + }; + obj.metadata.title = document.title; + // set mode too... + obj.highlightMode = module.highlightMode; + + // stringify the json and send it into chainpad + return stringify(obj); + }; + var onLocal = config.onLocal = function () { if (initializing) { return; } if (readOnly) { return; } editor.save(); - var textValue = canonicalize($textarea.val()); - var obj = {content: textValue}; - // append the userlist to the hyperjson structure - obj.metadata = { - users: userList - }; - if (!isDefaultTitle()) { - obj.metadata.title = document.title; - } - - // set mode too... - obj.highlightMode = module.highlightMode; - - // stringify the json and send it into chainpad - var shjson = stringify(obj); + var textValue = canonicalize($textarea.val()); + var shjson = stringifyInner(textValue); module.patchText(shjson); @@ -200,7 +207,7 @@ define([ myData[myID] = { name: myUserName }; - addToUserList(myData); + addToUserData(myData); Cryptpad.setAttribute('username', myUserName, function (err, data) { if (err) { console.log("Couldn't set username"); @@ -256,13 +263,10 @@ define([ }; var suggestName = function () { - var parsed = Cryptpad.parsePadUrl(window.location.href); - var name = Cryptpad.getDefaultName(parsed, []); - - if (Cryptpad.isDefaultName(parsed, document.title)) { - return getHeadingText() || document.title; + if (document.title === defaultName) { + return getHeadingText() || ""; } else { - return document.title || getHeadingText() || name; + return document.title || getHeadingText() || defaultName; } }; @@ -308,16 +312,68 @@ define([ onLocal(); }; - var onInit = config.onInit = function (info) { - var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); - toolbarList = info.userList; + var renameCb = function (err, title) { + if (err) { return; } + document.title = title; + onLocal(); + }; + + var updateTitle = function (newTitle) { + if (newTitle === document.title) { return; } + // Change the title now, and set it back to the old value if there is an error + var oldTitle = document.title; + document.title = newTitle; + Cryptpad.renamePad(newTitle, function (err, data) { + if (err) { + console.log("Couldn't set pad title"); + console.error(err); + document.title = oldTitle; + return; + } + document.title = data; + $bar.find('.' + Toolbar.constants.title).find('span.title').text(data); + $bar.find('.' + Toolbar.constants.title).find('input').val(data); + }); + }; + + var updateDefaultTitle = function (defaultTitle) { + defaultName = defaultTitle; + $bar.find('.' + Toolbar.constants.title).find('input').attr("placeholder", defaultName); + }; + + var updateMetadata = function(shjson) { + // Extract the user list (metadata) from the hyperjson + var json = (shjson === "") ? "" : JSON.parse(shjson); + if (json && json.metadata) { + if (json.metadata.users) { + var userData = json.metadata.users; + // Update the local user data + addToUserData(userData); + } + if (json.metadata.defaultTitle) { + updateDefaultTitle(json.metadata.defaultTitle); + } + if (typeof json.metadata.title !== "undefined") { + updateTitle(json.metadata.title); + } + } + }; + + var onInit = config.onInit = function (info) { + userList = info.userList; var config = { - userData: userList, + userData: userData, readOnly: readOnly, - ifrw: ifrw + ifrw: ifrw, + title: { + onRename: renameCb, + defaultName: defaultName, + suggestName: suggestName + }, + common: Cryptpad }; if (readOnly) {delete config.changeNameID; } - toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config); + toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, config); var $rightside = $bar.find('.' + Toolbar.constants.rightside); var $userBlock = $bar.find('.' + Toolbar.constants.username); @@ -336,8 +392,8 @@ define([ /* add a "change username" button */ getLastName(function (err, lastName) { userNameButtonObject.lastName = lastName; - var $username = module.$userNameButton = Cryptpad.createButton('username', false, userNameButtonObject, setName); - $userBlock.append($username).hide(); + var $username = module.$userNameButton = Cryptpad.createButton('username', false, userNameButtonObject, setName).hide(); + $userBlock.append($username); }); /* add an export button */ @@ -350,13 +406,8 @@ define([ $rightside.append($import); /* add a rename button */ - var renameCb = function (err, title) { - if (err) { return; } - document.title = title; - onLocal(); - }; - var $setTitle = Cryptpad.createButton('rename', true, {suggestName: suggestName}, renameCb); - $rightside.append($setTitle); + //var $setTitle = Cryptpad.createButton('rename', true, {suggestName: suggestName}, renameCb); + //$rightside.append($setTitle); } /* add a forget button */ @@ -454,47 +505,10 @@ define([ console.error(err); return; } - document.title = title || info.channel.slice(0, 8); - Cryptpad.setPadTitle(title, function (err, data) { - if (err) { - console.log("Unable to set pad title"); - console.error(err); - return; - } - }); - }); - }; - - var updateTitle = function (newTitle) { - if (newTitle === document.title) { return; } - // Change the title now, and set it back to the old value if there is an error - var oldTitle = document.title; - document.title = newTitle; - Cryptpad.setPadTitle(newTitle, function (err, data) { - if (err) { - console.log("Couldn't set pad title"); - console.error(err); - document.title = oldTitle; - return; - } + updateTitle(title || defaultName); }); }; - var updateMetadata = function(shjson) { - // Extract the user list (metadata) from the hyperjson - var json = (shjson === "") ? "" : JSON.parse(shjson); - if (json && json.metadata) { - if (json.metadata.users) { - var userData = json.metadata.users; - // Update the local user data - addToUserList(userData); - } - if (json.metadata.title) { - updateTitle(json.metadata.title); - } - } - }; - var unnotify = module.unnotify = function () { if (module.tabNotification && typeof(module.tabNotification.cancel) === 'function') { @@ -560,16 +574,16 @@ define([ // Update the toolbar list: // Add the current user in the metadata if he has edit rights if (readOnly) { return; } - myData[myID] = { - name: "" - }; - addToUserList(myData); if (typeof(lastName) === 'string' && lastName.length) { setName(lastName); } else { + myData[myID] = { + name: "" + }; + addToUserData(myData); + onLocal(); module.$userNameButton.click(); } - onLocal(); }); }; @@ -641,18 +655,8 @@ define([ editor.scrollTo(scroll.left, scroll.top); if (!readOnly) { - var localDoc = canonicalize($textarea.val()); - var hjson2 = { - content: localDoc, - metadata: { - users: userList - }, - highlightMode: highlightMode, - }; - if (!isDefaultTitle()) { - hjson2.metadata.title = document.title; - } - var shjson2 = stringify(hjson2); + var textValue = canonicalize($textarea.val()); + var shjson2 = stringifyInner(textValue); if (shjson2 !== shjson) { console.error("shjson2 !== shjson"); TextPatcher.log(shjson, TextPatcher.diff(shjson, shjson2)); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 7e2724ea3..b691f2ee4 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -302,13 +302,17 @@ define([ var type = parsed.type; var untitledIndex = 1; var name = (Messages.type)[type] + ' - ' + new Date().toString().split(' ').slice(0,4).join(' '); - if (isNameAvailable(name, parsed, recentPads)) { return name; } - while (!isNameAvailable(name + ' - ' + untitledIndex, parsed, recentPads)) { untitledIndex++; } - return name + ' - ' + untitledIndex; + return name; + /* + * Pad titles are shared in the document so it does not make sense anymore to avoid duplicates + if (isNameAvailable(name, parsed, recentPads)) { return name; } + while (!isNameAvailable(name + ' - ' + untitledIndex, parsed, recentPads)) { untitledIndex++; } + return name + ' - ' + untitledIndex; + */ }; var isDefaultName = common.isDefaultName = function (parsed, title) { var name = getDefaultName(parsed, []); - return title.slice(0, name.length) === name; + return title === name; }; var makePad = function (href, title) { @@ -622,7 +626,21 @@ define([ var renamePad = common.renamePad = function (title, callback) { if (title === null) { return; } - common.causesNamingConflict(title, function (err, conflicts) { + if (title.trim() === "") { + var parsed = parsePadUrl(window.location.href); + title = getDefaultName(parsed); + } + + common.setPadTitle(title, function (err, data) { + if (err) { + console.log("unable to set pad title"); + console.log(err); + return; + } + callback(null, title); + }); + /* Pad titles are shared in the document. We don't check for duplicates anymore. + common.causesNamingConflict(title, function (err, conflicts) { if (err) { console.log("Unable to determine if name caused a conflict"); console.error(err); @@ -644,6 +662,7 @@ define([ callback(null, title); }); }); + */ }; var createButton = common.createButton = function (type, rightside, data, callback) { var button; diff --git a/www/common/toolbar.js b/www/common/toolbar.js index bd58f324a..2fc0c112d 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -36,6 +36,7 @@ define([ var DROPDOWN_CONTAINER_CLS = Bar.constants.dropdownContainer = "cryptpad-dropdown-container"; var DROPDOWN_CLS = Bar.constants.dropdown = "cryptpad-dropdown"; var TITLE_CLS = Bar.constants.title = "cryptpad-title"; + var USER_CLS = Bar.constants.userAdmin = "cryptpad-user"; /** Key in the localStore which indicates realtime activity should be disallowed. */ // TODO remove? will never be used in cryptpad @@ -51,6 +52,7 @@ define([ var $style; var firstConnection = true; + var lagErrors = 0; var styleToolbar = function ($container, href) { href = href || '/customize/toolbar.css'; @@ -103,34 +105,6 @@ define([ 'class': USERBUTTONS_CONTAINER_CLS }).appendTo($userlistElement); - var $editIcon = $('