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..a1ff01d8e 100644 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -22,6 +22,15 @@ define(['/customize/languageSelector.js', messages = $.extend(true, {}, Default, map[language]); } + 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..a674db185 100644 --- a/customize.dist/src/toolbar.less +++ b/customize.dist/src/toolbar.less @@ -39,7 +39,7 @@ } } - button, .rightside-element { + button, select, .rightside-element { height: 26px; padding-right: 5px; padding-left: 5px; @@ -108,28 +108,92 @@ .cryptpad-toolbar-top { display: block; text-align: center; + height: 3em; + position: relative; + margin-bottom: 3px; + @media screen and (max-width: 400px) { + height: 6em; + } .cryptpad-title { - text-align: center; + span { + font-size: 1.5em; + vertical-align: middle; + line-height: 2em; + &:hover { + border: 1px solid #888; + border-radius: 2px; + background: white; + padding: 5px; + } + } 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: 3em; + @media screen and (max-width: 400px) { + top: 3em; + } + @media screen and (min-width: 401px) { + top: 0px; + } + + a.cryptpad-logo { + cursor: pointer; + height: 3em; + border: 1px solid #aaa; + border-radius: @border-radius; + padding: 0px 5px; + text-decoration: none; + color: inherit; + img { + vertical-align: middle; + height: 3em; + 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; } } } diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css index 9cbde4f5d..5bf1dc0bf 100644 --- a/customize.dist/toolbar.css +++ b/customize.dist/toolbar.css @@ -38,6 +38,7 @@ margin: 2px 0px 2px 4px; } .cryptpad-toolbar button, +.cryptpad-toolbar select, .cryptpad-toolbar .rightside-element { height: 26px; padding-right: 5px; @@ -104,30 +105,105 @@ .cryptpad-toolbar-top { display: block; text-align: center; + height: 3em; + position: relative; + margin-bottom: 3px; } -.cryptpad-toolbar-top .cryptpad-title { - text-align: center; +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top { + height: 6em; + } +} +.cryptpad-toolbar-top .cryptpad-title span { + font-size: 1.5em; + vertical-align: middle; + line-height: 2em; +} +.cryptpad-toolbar-top .cryptpad-title span:hover { + border: 1px solid #888; + border-radius: 2px; + background: white; + padding: 5px; } .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; + padding: 0px 5px; } -.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; +.cryptpad-toolbar-top .cryptpad-link { + position: absolute; + left: 0px; + height: 3em; +} +@media screen and (max-width: 400px) { + .cryptpad-toolbar-top .cryptpad-link { + top: 3em; + } +} +@media screen and (min-width: 401px) { + .cryptpad-toolbar-top .cryptpad-link { + top: 0px; + } +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo { + cursor: pointer; + height: 3em; + border: 1px solid #aaa; + border-radius: 1px; + padding: 0px 5px; + text-decoration: none; + color: inherit; +} +.cryptpad-toolbar-top .cryptpad-link a.cryptpad-logo img { + vertical-align: middle; + height: 3em; + 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; diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 57f50a33a..49faa6f2e 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 = {}; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 51c8f73a7..1821cde81 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 = {}; 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..77ecd84be 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, @@ -176,6 +179,9 @@ define([ if (!isDefaultTitle()) { obj.metadata.title = document.title; } + else { + obj.metadata.title = ""; + } // set mode too... obj.highlightMode = module.highlightMode; @@ -256,13 +262,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 (Cryptpad.isDefaultName(parsedHash, document.title)) { + return getHeadingText() || defaultName; } else { - return document.title || getHeadingText() || name; + return document.title || getHeadingText() || defaultName; } }; @@ -308,13 +311,23 @@ define([ onLocal(); }; + var renameCb = function (err, title) { + if (err) { return; } + document.title = title; + onLocal(); + }; + var onInit = config.onInit = function (info) { - var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); toolbarList = info.userList; var config = { userData: userList, readOnly: readOnly, - ifrw: ifrw + ifrw: ifrw, + title: { + onRename: renameCb, + defaultName: defaultName + }, + common: Cryptpad }; if (readOnly) {delete config.changeNameID; } toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config); @@ -336,8 +349,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,11 +363,6 @@ 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); } @@ -454,14 +462,7 @@ 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; - } - }); + updateTitle(title || defaultName); }); }; @@ -470,13 +471,16 @@ define([ // 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) { + 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').text(data); + $bar.find('.' + Toolbar.constants.title).find('input').val(data); }); }; @@ -489,7 +493,7 @@ define([ // Update the local user data addToUserList(userData); } - if (json.metadata.title) { + if (typeof json.metadata.title !== "undefined") { updateTitle(json.metadata.title); } } @@ -652,6 +656,9 @@ define([ if (!isDefaultTitle()) { hjson2.metadata.title = document.title; } + else { + hjson2.metadata.title = ""; + } var shjson2 = stringify(hjson2); if (shjson2 !== shjson) { console.error("shjson2 !== shjson"); diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 28e218046..117c07dcc 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 @@ -195,7 +196,7 @@ define([ if (n === 1) { return '; + ' + Messages.oneViewer; } return '; + ' + Messages._getKey('viewers', [n]); }; - var updateUserList = function (myUserName, userlistElement, userList, userData, readOnly, $stateElement) { + var updateUserList = function (myUserName, userlistElement, userList, userData, readOnly, $stateElement, $userAdminElement) { var meIdx = userList.indexOf(myUserName); if (meIdx === -1) { $stateElement.text(Messages.synchronizing); @@ -206,7 +207,7 @@ define([ // Make sure the user block elements are displayed var $userButtons = $(userlistElement).find("#userButtons"); $userButtons.show(); - var $userElement = $(userlistElement).find('.' + USERNAME_CLS); + var $userElement = $userAdminElement.find('.' + USERNAME_CLS); $userElement.show(); var numberOfUsers = userList.length; @@ -261,7 +262,7 @@ define([ if (!name) { name = Messages.anonymous; } - $userElement.find("button").html(icon + ' ' + name); + $userElement.find("button").html(icon + ' ' + name).show(); } }; @@ -303,7 +304,60 @@ define([ $(lagElement).append(lagLight); }; + var createLinkToMain = function ($topContainer) { + var $linkContainer = $('', { + 'class': "cryptpad-link" + }).appendTo($topContainer); + var $imgTag = $('', { + src: "/customize/cryptofist_mini.png", + alt: "Cryptpad", + 'class': "cryptofist" + }); + var $aTagSmall = $('', { + href: "/", + title: Messages.header_logoTitle, + 'class': "cryptpad-logo" + }).append($imgTag); + $span = $('').text('CryptPad'); + var $aTagBig = $aTagSmall.clone().addClass('big').append($span); + $aTagSmall.addClass('small'); + + $linkContainer.append($aTagSmall).append($aTagBig); + }; + + var createUserAdmin = function ($topContainer) { + var $userContainer = $('', { + 'class': USER_CLS + }).appendTo($topContainer); + + var $span = $('' , { + 'class': 'cryptpad-language' + }); + var $select = $('', { type: 'text', placeholder: placeholder @@ -335,6 +391,10 @@ define([ $text.show(); }); } + else if (e.which === 27) { + $input.hide(); + $text.show(); + } }); $text.on('click', function () { $text.hide(); @@ -342,9 +402,11 @@ define([ $input.show(); $input.focus(); }); + return $titleContainer; }; var create = Bar.create = function ($container, myUserName, realtime, getLag, userList, config) { + config = config || {}; var readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1; var Cryptpad = config.common; @@ -353,6 +415,8 @@ define([ var spinner = createSpinner(toolbar.find('.' + RIGHTSIDE_CLS)); var lagElement = createLagElement(toolbar.find('.' + RIGHTSIDE_CLS)); var $titleElement = createTitle(toolbar.find('.' + TOP_CLS), readOnly, config.title, Cryptpad); + var $linkElement = createLinkToMain(toolbar.find('.' + TOP_CLS)); + var $userAdminElement = createUserAdmin(toolbar.find('.' + TOP_CLS)); var userData = config.userData; // readOnly = 1 (readOnly enabled), 0 (disabled), -1 (old pad without readOnly mode) var saveElement; @@ -368,7 +432,15 @@ define([ } $container.find('.cryptpad-dropdown').hide(); }; - $(config.ifrw).on('click',removeDropdowns); + var cancelEditTitle = function (e) { + if ($(e.target).parents('.' + TITLE_CLS).length) { + return; + } + $titleElement.find('input').hide(); + $titleElement.find('span').show(); + }; + $(config.ifrw).on('click', removeDropdowns); + $(config.ifrw).on('click', cancelEditTitle); if (config.ifrw.$('iframe').length) { var innerIfrw = config.ifrw.$('iframe').each(function (i, el) { $(el.contentWindow).on('click', removeDropdowns); @@ -383,7 +455,7 @@ define([ if(newUserData) { // Someone has changed his name/color userData = newUserData; } - updateUserList(myUserName, userListElement, users, userData, readOnly, $stateElement); + updateUserList(myUserName, userListElement, users, userData, readOnly, $stateElement, $userAdminElement); }; var ks = function () { diff --git a/www/pad/index.html b/www/pad/index.html index 2bab2dee9..13f0d2938 100644 --- a/www/pad/index.html +++ b/www/pad/index.html @@ -21,7 +21,7 @@ } #pad-iframe { position:fixed; - top:2.5em; + top:0px; left:0px; bottom:0px; right:0px; diff --git a/www/pad/main.js b/www/pad/main.js index 689d70e86..0ca608b21 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -253,7 +253,7 @@ define([ }; var initializing = true; - var userList = module.userList = {}; // List of pretty name of all users (mapped with their server ID) + var userList = module.userList = {}; // List of pretty names for all users (mapped with their ID) var toolbarList; // List of users still connected to the channel (server IDs) var addToUserList = function(data) { var users = module.users; @@ -556,8 +556,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 */ @@ -604,8 +604,7 @@ define([ console.log("Couldn't get pad title"); return; } - updateTitle(title || info.channel.slice(0, 8)); - document.title = title || info.channel.slice(0, 8); + updateTitle(title || defaultName); }); }; diff --git a/www/slide/index.html b/www/slide/index.html index b36464b0e..f08782eb2 100644 --- a/www/slide/index.html +++ b/www/slide/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/slide/main.js b/www/slide/main.js index a5c41633a..3e48d745a 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -62,10 +62,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, @@ -211,6 +214,9 @@ define([ if (!isDefaultTitle()) { obj.metadata.title = APP.title; } + else { + obj.metadata.title = ""; + } if (textColor) { obj.metadata.color = textColor; } @@ -286,13 +292,10 @@ define([ }; var suggestName = function () { - var parsed = Cryptpad.parsePadUrl(window.location.href); - var name = Cryptpad.getDefaultName(parsed, []); - - if (Cryptpad.isDefaultName(parsed, APP.title)) { - return getHeadingText() || APP.title; + if (Cryptpad.isDefaultName(parsedHash, APP.title)) { + return getHeadingText() || defaultName; } else { - return APP.title || getHeadingText() || name; + return APP.title || getHeadingText() || defaultName; } }; @@ -344,7 +347,7 @@ define([ var oldTitle = APP.title; APP.title = newTitle; setTabTitle(); - Cryptpad.setPadTitle(newTitle, function (err, data) { + Cryptpad.renamePad(newTitle, function (err, data) { if (err) { console.log("Couldn't set pad title"); console.error(err); @@ -352,6 +355,10 @@ define([ setTabTitle(); return; } + APP.title = data; + setTabTitle(); + $bar.find('.' + Toolbar.constants.title).find('span').text(data); + $bar.find('.' + Toolbar.constants.title).find('input').val(data); }); }; @@ -378,20 +385,31 @@ define([ // Update the local user data addToUserList(userData); } - if (json.metadata.title) { + if (typeof json.metadata.title !== "undefined") { updateTitle(json.metadata.title); } updateColors(json.metadata.color, json.metadata.backColor); } }; + var renameCb = function (err, title) { + if (err) { return; } + APP.title = title; + setTabTitle(); + onLocal(); + }; + var onInit = config.onInit = function (info) { - var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox'); toolbarList = info.userList; var config = { userData: userList, readOnly: readOnly, - ifrw: $('#pad-iframe')[0].contentWindow + ifrw: ifrw, + title: { + onRename: renameCb, + defaultName: defaultName + }, + common: Cryptpad }; if (readOnly) {delete config.changeNameID; } toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config); @@ -413,8 +431,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 */ @@ -427,12 +445,6 @@ define([ $rightside.append($import); /* add a rename button */ - var renameCb = function (err, title) { - if (err) { return; } - APP.title = title; - setTabTitle(); - onLocal(); - }; var $setTitle = Cryptpad.createButton('rename', true, {suggestName: suggestName}, renameCb); $rightside.append($setTitle); } @@ -576,14 +588,7 @@ define([ console.error(err); return; } - document.title = APP.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; - } - }); + updateTitle(title || defaultName); }); };