Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging-soon
commit
6ae851ffdd
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 '?'; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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: 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;
|
||||
}
|
||||
|
|
|
@ -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 !';
|
||||
|
|
|
@ -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!';
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
#iframe-container {
|
||||
position: fixed;
|
||||
top: 2.6em;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
|
|
206
www/code/main.js
206
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 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;
|
||||
}
|
||||
});
|
||||
updateTitle(title || defaultName);
|
||||
});
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = $('<button>', {
|
||||
'class': 'userlist dropbtn edit',
|
||||
});
|
||||
var $editIconSmall = $editIcon.clone().addClass('small');
|
||||
var $viewIcon = $('<button>', {
|
||||
'class': 'userlist dropbtn view',
|
||||
});
|
||||
var $viewIconSmall = $viewIcon.clone().addClass('small');
|
||||
|
||||
var $shareTitle = $('<h2>').text(Messages.share);
|
||||
var $dropdownEditUsers = $('<p>', {'class': USERLIST_CLS});
|
||||
var $dropdownEditShare = $('<p>', {'class': EDITSHARE_CLS});
|
||||
if (readOnly !== 1) {
|
||||
$dropdownEditShare.append($shareTitle);
|
||||
}
|
||||
var $dropdownEditContainer = $('<div>', {'class': DROPDOWN_CONTAINER_CLS});
|
||||
var $dropdownEdit = $('<div>', {
|
||||
id: "cryptpad-dropdown-edit",
|
||||
'class': DROPDOWN_CLS
|
||||
}).append($dropdownEditUsers).append($dropdownEditShare);
|
||||
|
||||
var $dropdownViewShare = $('<p>', {'class': VIEWSHARE_CLS}).append($shareTitle.clone());
|
||||
var $dropdownViewContainer = $('<div>', {'class': DROPDOWN_CONTAINER_CLS});
|
||||
var $dropdownView = $('<div>', {
|
||||
id: "cryptpad-dropdown-view",
|
||||
'class': DROPDOWN_CLS
|
||||
}).append($dropdownViewShare);
|
||||
|
||||
var createHandler = function ($elmt) {
|
||||
return function () {
|
||||
if ($elmt.is(':visible')) {
|
||||
|
@ -141,29 +115,59 @@ define([
|
|||
$elmt.show();
|
||||
};
|
||||
};
|
||||
|
||||
var fa_caretdown = '<span class="fa fa-caret-down" style="font-family:FontAwesome;"></span>';
|
||||
|
||||
// User list button
|
||||
var $editIcon = $('<button>', {
|
||||
'class': 'userlist dropbtn edit',
|
||||
});
|
||||
var $editIconSmall = $editIcon.clone().addClass('small');
|
||||
var $dropdownEditUsers = $('<p>', {'class': USERLIST_CLS});
|
||||
var $dropdownEditContainer = $('<div>', {'class': DROPDOWN_CONTAINER_CLS});
|
||||
var $dropdownEdit = $('<div>', {
|
||||
id: "cryptpad-dropdown-edit",
|
||||
'class': DROPDOWN_CLS
|
||||
}).append($dropdownEditUsers); //.append($dropdownEditShare);
|
||||
$editIcon.click(createHandler($dropdownEdit));
|
||||
$editIconSmall.click(createHandler($dropdownEdit));
|
||||
$viewIcon.click(createHandler($dropdownView));
|
||||
$viewIconSmall.click(createHandler($dropdownView));
|
||||
|
||||
$dropdownEditContainer.append($editIcon).append($editIconSmall).append($dropdownEdit);
|
||||
$dropdownViewContainer.append($viewIcon).append($viewIconSmall).append($dropdownView);
|
||||
|
||||
$listElement.append($dropdownEditContainer);
|
||||
if (readOnly !== -1) {
|
||||
$listElement.append($dropdownViewContainer);
|
||||
|
||||
// Share button
|
||||
var fa_share = '<span class="fa fa-share-alt" style="font-family:FontAwesome;"></span>';
|
||||
var fa_editusers = '<span class="fa fa-users" style="font-family:FontAwesome;"></span>';
|
||||
var fa_viewusers = '<span class="fa fa-eye" style="font-family:FontAwesome;"></span>';
|
||||
var $shareIcon = $('<button>', {
|
||||
'class': 'userlist dropbtn share',
|
||||
}).html(fa_share + ' ' + Messages.shareButton + ' ' + fa_caretdown);
|
||||
var $shareIconSmall = $shareIcon.clone().addClass('small').html(fa_share + ' ' + fa_caretdown);
|
||||
var $shareTitle = $('<h2>').html(fa_editusers + ' ' + Messages.shareEdit);
|
||||
var $shareTitleView = $('<h2>').html(fa_viewusers + ' ' + Messages.shareView);
|
||||
var $dropdownShareP = $('<p>', {'class': EDITSHARE_CLS}).append($shareTitle);
|
||||
var $dropdownSharePView = $('<p>', {'class': VIEWSHARE_CLS}).append($shareTitleView);
|
||||
var $dropdownShareContainer = $('<div>', {'class': DROPDOWN_CONTAINER_CLS});
|
||||
var $dropdownShare = $('<div>', {
|
||||
id: "cryptpad-dropdown-share",
|
||||
'class': DROPDOWN_CLS
|
||||
});
|
||||
if (readOnly !== 1) {
|
||||
// Hide the "Share edit URL" section when in read-only mode
|
||||
$dropdownShare.append($dropdownShareP);
|
||||
}
|
||||
|
||||
|
||||
$dropdownShare.append($dropdownSharePView);
|
||||
$shareIcon.click(createHandler($dropdownShare));
|
||||
$shareIconSmall.click(createHandler($dropdownShare));
|
||||
$dropdownShareContainer.append($shareIcon).append($shareIconSmall).append($dropdownShare);
|
||||
$listElement.append($dropdownShareContainer);
|
||||
};
|
||||
|
||||
var createUserList = function ($container, readOnly) {
|
||||
var $state = $('<span>', {'class': STATE_CLS}).text(Messages.synchronizing);
|
||||
var $usernameElement = $('<span>', {'class': USERNAME_CLS});
|
||||
var $userlist = $('<div>', {
|
||||
'class': USER_LIST_CLS,
|
||||
id: uid(),
|
||||
}).append($state).append($usernameElement);
|
||||
}).append($state);
|
||||
createUserButtons($userlist, readOnly);
|
||||
$container.append($userlist);
|
||||
return $userlist[0];
|
||||
|
@ -195,7 +199,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);
|
||||
|
@ -203,27 +207,26 @@ define([
|
|||
}
|
||||
$stateElement.text('');
|
||||
|
||||
// Make sure the user block elements are displayed
|
||||
// Make sure the elements are displayed
|
||||
var $userButtons = $(userlistElement).find("#userButtons");
|
||||
$userButtons.show();
|
||||
var $userElement = $(userlistElement).find('.' + USERNAME_CLS);
|
||||
$userElement.show();
|
||||
|
||||
var numberOfUsers = userList.length;
|
||||
|
||||
// If we are using old pads (readonly unavailable), only editing users are in userList.
|
||||
// With new pads, we also have readonly users in userList, so we have to intersect with
|
||||
// the userData to have only the editing users. We can't use userData directly since it
|
||||
// contains data about users that have already left the channel.
|
||||
// may contain data about users that have already left the channel.
|
||||
userList = readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
|
||||
|
||||
var numberOfViewUsers = numberOfUsers - userList.length;
|
||||
var numberOfEditUsers = userList.length;
|
||||
var numberOfViewUsers = numberOfUsers - numberOfEditUsers;
|
||||
|
||||
// Names of editing users
|
||||
var editUsersNames = getOtherUsers(myUserName, userList, userData);
|
||||
|
||||
// Number of anonymous editing users
|
||||
var anonymous = numberOfUsers - editUsersNames.length;
|
||||
var anonymous = numberOfEditUsers - editUsersNames.length;
|
||||
|
||||
// Update the userlist
|
||||
var editUsersList = '';
|
||||
|
@ -235,9 +238,20 @@ define([
|
|||
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
|
||||
editUsersNames.push('<span class="anonymous">' + anonymous + ' ' + text + '</span>');
|
||||
}
|
||||
if (numberOfViewUsers > 0) {
|
||||
var viewText = '<span class="viewer">';
|
||||
if (numberOfEditUsers > 0) {
|
||||
editUsersNames.push('');
|
||||
viewText += Messages.and + ' ';
|
||||
}
|
||||
var viewerText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer;
|
||||
viewText += numberOfViewUsers + ' ' + viewerText + '</span>';
|
||||
editUsersNames.push(viewText);
|
||||
}
|
||||
if (editUsersNames.length > 0) {
|
||||
editUsersList += editUsersNames.join('<br>');
|
||||
}
|
||||
|
||||
var $usersTitle = $('<h2>').text(Messages.users);
|
||||
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
|
||||
$editUsers.html('').append($usersTitle).append(editUsersList);
|
||||
|
@ -246,13 +260,15 @@ define([
|
|||
var fa_caretdown = '<span class="fa fa-caret-down" style="font-family:FontAwesome;"></span>';
|
||||
var fa_editusers = '<span class="fa fa-users" style="font-family:FontAwesome;"></span>';
|
||||
var fa_viewusers = '<span class="fa fa-eye" style="font-family:FontAwesome;"></span>';
|
||||
$userButtons.find('.userlist.edit').html(fa_editusers + ' ' + userList.length + ' ' + Messages.editing + ' ' + fa_caretdown);
|
||||
$userButtons.find('.userlist.edit.small').html(fa_editusers + ' ' + userList.length + ' ' + fa_caretdown);
|
||||
$userButtons.find('.userlist.view').html(fa_viewusers + ' ' + numberOfViewUsers + ' ' + Messages.viewing + ' ' + fa_caretdown);
|
||||
$userButtons.find('.userlist.view.small').html(fa_viewusers + ' ' + numberOfViewUsers + ' ' + fa_caretdown);
|
||||
var viewersText = numberOfViewUsers > 1 ? Messages.viewers : Messages.viewer;
|
||||
var editorsText = numberOfEditUsers > 1 ? Messages.editors : Messages.editor;
|
||||
$userButtons.find('.userlist.edit').html(fa_editusers + ' ' + numberOfEditUsers + ' ' + editorsText + ' ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + viewersText + ' ' + fa_caretdown);
|
||||
$userButtons.find('.userlist.edit.small').html(fa_editusers + ' ' + numberOfEditUsers + ' ' + fa_viewusers + ' ' + numberOfViewUsers + ' ' + fa_caretdown);
|
||||
|
||||
// Change username button
|
||||
var $userElement = $userAdminElement.find('.' + USERNAME_CLS);
|
||||
$userElement.show();
|
||||
if (readOnly === 1) {
|
||||
// TODO
|
||||
$userElement.html('<span class="' + READONLY_CLS + '">' + Messages.readonly + '</span>');
|
||||
}
|
||||
else {
|
||||
|
@ -261,6 +277,7 @@ define([
|
|||
if (!name) {
|
||||
name = Messages.anonymous;
|
||||
}
|
||||
$userElement.find("button").show();
|
||||
$userElement.find("button").html(icon + ' ' + name);
|
||||
}
|
||||
};
|
||||
|
@ -283,64 +300,181 @@ define([
|
|||
'class': 'lag'
|
||||
});
|
||||
var title;
|
||||
if(lag) {
|
||||
firstConnection = false;
|
||||
title = Messages.lag + ' : ' + lag + ' ms\n';
|
||||
if (lag.waiting || lag > 1000) {
|
||||
lagLight.addClass('lag-orange');
|
||||
title += Messages.orangeLight;
|
||||
} else {
|
||||
lagLight.addClass('lag-green');
|
||||
title += Messages.greenLight;
|
||||
}
|
||||
if (typeof lag !== "undefined") {
|
||||
lagErrors = 0;
|
||||
firstConnection = false;
|
||||
title = Messages.lag + ' : ' + lag + ' ms\n';
|
||||
if (lag.waiting || lag > 1000) {
|
||||
lagLight.addClass('lag-orange');
|
||||
title += Messages.orangeLight;
|
||||
} else {
|
||||
lagLight.addClass('lag-green');
|
||||
title += Messages.greenLight;
|
||||
}
|
||||
}
|
||||
else if (!firstConnection){
|
||||
lagLight.addClass('lag-red');
|
||||
title = Messages.redLight;
|
||||
else if (!firstConnection) {
|
||||
lagErrors++;
|
||||
// Display the red light at the 2nd failed attemp to get the lag
|
||||
if (lagErrors > 1) {
|
||||
lagLight.addClass('lag-red');
|
||||
title = Messages.redLight;
|
||||
}
|
||||
}
|
||||
if (title) {
|
||||
lagLight.attr('title', title);
|
||||
$(lagElement).html('');
|
||||
$(lagElement).append(lagLight);
|
||||
}
|
||||
lagLight.attr('title', title);
|
||||
$(lagElement).html('');
|
||||
$(lagElement).append(lagLight);
|
||||
};
|
||||
|
||||
var createTitle = function ($container, readOnly, cb) {
|
||||
var createLinkToMain = function ($topContainer) {
|
||||
var $linkContainer = $('<span>', {
|
||||
'class': "cryptpad-link"
|
||||
}).appendTo($topContainer);
|
||||
var $imgTag = $('<img>', {
|
||||
src: "/customize/cryptofist_mini.png",
|
||||
alt: "Cryptpad",
|
||||
'class': "cryptofist"
|
||||
});
|
||||
|
||||
// We need to override the "a" tag action here because it is inside the iframe!
|
||||
var $aTagSmall = $('<a>', {
|
||||
href: "/",
|
||||
title: Messages.header_logoTitle,
|
||||
'class': "cryptpad-logo"
|
||||
}).append($imgTag);
|
||||
var $span = $('<span>').text('CryptPad');
|
||||
var $aTagBig = $aTagSmall.clone().addClass('big').append($span);
|
||||
$aTagSmall.addClass('small');
|
||||
var onClick = function (e) {
|
||||
e.preventDefault();
|
||||
window.location = "/";
|
||||
};
|
||||
|
||||
$aTagBig.click(onClick);
|
||||
$aTagSmall.click(onClick);
|
||||
|
||||
$linkContainer.append($aTagSmall).append($aTagBig);
|
||||
};
|
||||
|
||||
var createUserAdmin = function ($topContainer) {
|
||||
var $userContainer = $('<span>', {
|
||||
'class': USER_CLS
|
||||
}).appendTo($topContainer);
|
||||
|
||||
var $span = $('<span>' , {
|
||||
'class': 'cryptpad-language'
|
||||
});
|
||||
var $select = $('<select>', {
|
||||
'id': 'language-selector'
|
||||
}).appendTo($userContainer);
|
||||
|
||||
var languages = Messages._languages;
|
||||
for (var l in languages) {
|
||||
$('<option>', {
|
||||
value: l
|
||||
}).text(languages[l]).appendTo($select);
|
||||
}
|
||||
|
||||
Messages._initSelector($select);
|
||||
|
||||
$select.on('mousedown', function (e) {
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
});
|
||||
|
||||
var $usernameElement = $('<span>', {'class': USERNAME_CLS}).appendTo($userContainer);
|
||||
|
||||
return $userContainer;
|
||||
};
|
||||
|
||||
var createTitle = function ($container, readOnly, config, Cryptpad) {
|
||||
config = config || {};
|
||||
var callback = config.onRename;
|
||||
var placeholder = config.defaultName;
|
||||
var suggestName = config.suggestName;
|
||||
|
||||
// Buttons
|
||||
var $titleContainer = $('<span>', {
|
||||
id: 'toolbarTitle',
|
||||
'class': TITLE_CLS
|
||||
}).appendTo($container);
|
||||
var $text = $('<span>').appendTo($titleContainer);
|
||||
if (readOnly === 1) { return; }
|
||||
var $text = $('<span>', {
|
||||
'class': 'title'
|
||||
}).appendTo($titleContainer);
|
||||
var $pencilIcon = $('<span>', {
|
||||
'class': 'pencilIcon'
|
||||
});
|
||||
if (readOnly === 1 || typeof(Cryptpad) === "undefined") { return $titleContainer; }
|
||||
var $input = $('<input>', {
|
||||
type: 'text'
|
||||
type: 'text',
|
||||
placeholder: placeholder
|
||||
}).appendTo($titleContainer).hide();
|
||||
if (readOnly !== 1) {
|
||||
$text.attr("title", Messages.clickToEdit);
|
||||
$text.addClass("editable");
|
||||
var $icon = $('<span>', {
|
||||
'class': 'fa fa-pencil readonly',
|
||||
style: 'font-family: FontAwesome;'
|
||||
});
|
||||
$pencilIcon.append($icon).appendTo($titleContainer);
|
||||
}
|
||||
|
||||
// Events
|
||||
$input.on('mousedown', function (e) {
|
||||
if (!$input.is(":focus")) {
|
||||
$input.focus();
|
||||
}
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
});
|
||||
$input.on('keyup', function (e) {
|
||||
if (e.which === 13) {
|
||||
Cryptpad.renamePad(title, function (err, newtitle) {
|
||||
var name = $input.val().trim();
|
||||
if (name === "") {
|
||||
name = $input.attr('placeholder');
|
||||
}
|
||||
Cryptpad.renamePad(name, function (err, newtitle) {
|
||||
if (err) { return; }
|
||||
$text.text(newtitle);
|
||||
cb(null, newtitle);
|
||||
callback(null, newtitle);
|
||||
$input.hide();
|
||||
$text.show();
|
||||
$pencilIcon.css('display', '');
|
||||
});
|
||||
}
|
||||
else if (e.which === 27) {
|
||||
$input.hide();
|
||||
$text.show();
|
||||
$pencilIcon.css('display', '');
|
||||
}
|
||||
});
|
||||
$text.on('click', function () {
|
||||
console.log('click');
|
||||
|
||||
var displayInput = function () {
|
||||
$text.hide();
|
||||
$input.val($text.text());
|
||||
$pencilIcon.css('display', 'none');
|
||||
var inputVal = suggestName() || "";
|
||||
$input.val(inputVal);
|
||||
$input.show();
|
||||
$input.focus();
|
||||
});
|
||||
};
|
||||
$text.on('click', displayInput);
|
||||
$pencilIcon.on('click', displayInput);
|
||||
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;
|
||||
|
||||
var toolbar = createRealtimeToolbar($container);
|
||||
var userListElement = createUserList(toolbar.find('.' + LEFTSIDE_CLS), readOnly);
|
||||
var spinner = createSpinner(toolbar.find('.' + RIGHTSIDE_CLS));
|
||||
var lagElement = createLagElement(toolbar.find('.' + RIGHTSIDE_CLS));
|
||||
var $titleElement = createTitle(toolbar.find('.' + TOP_CLS), readOnly, config.onRename);
|
||||
var lagElement = createLagElement($(userListElement));
|
||||
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;
|
||||
|
@ -356,23 +490,89 @@ 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.title').show();
|
||||
$titleElement.find('span.pencilIcon').css('display', '');
|
||||
};
|
||||
$(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);
|
||||
$(el.contentWindow).on('click', cancelEditTitle);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
userList.onChange = function(newUserData) {
|
||||
var users = userList.users;
|
||||
if (users.indexOf(myUserName) !== -1) { connected = true; }
|
||||
if (!connected) { return; }
|
||||
if(newUserData) { // Someone has changed his name/color
|
||||
userData = newUserData;
|
||||
}
|
||||
updateUserList(myUserName, userListElement, users, userData, readOnly, $stateElement);
|
||||
};
|
||||
// Update user list
|
||||
userList.change.push(function (newUserData) {
|
||||
var users = userList.users;
|
||||
if (users.indexOf(myUserName) !== -1) { connected = true; }
|
||||
if (!connected) { return; }
|
||||
/*if (newUserData) { // Someone has changed his name/color
|
||||
userData = newUserData;
|
||||
}*/
|
||||
updateUserList(myUserName, userListElement, users, userData, readOnly, $stateElement, $userAdminElement);
|
||||
});
|
||||
// Display notifications when users are joining/leaving the session
|
||||
var oldUserData;
|
||||
if (typeof Cryptpad !== "undefined") {
|
||||
var notify = function(type, name, oldname) {
|
||||
// type : 1 (+1 user), 0 (rename existing user), -1 (-1 user)
|
||||
if (typeof name === "undefined") { return; }
|
||||
name = (name === "") ? Messages.anonymous : name;
|
||||
switch(type) {
|
||||
case 1:
|
||||
Cryptpad.log(Messages._getKey("notifyJoined", [name]));
|
||||
break;
|
||||
case 0:
|
||||
oldname = (oldname === "") ? Messages.anonymous : oldname;
|
||||
Cryptpad.log(Messages._getKey("notifyRenamed", [oldname, name]));
|
||||
break;
|
||||
case -1:
|
||||
Cryptpad.log(Messages._getKey("notifyLeft", [name]));
|
||||
break;
|
||||
default:
|
||||
console.log("Invalid type of notification");
|
||||
break;
|
||||
}
|
||||
};
|
||||
userList.change.push(function (newdata) {
|
||||
// Notify for disconnected users
|
||||
if (typeof oldUserData !== "undefined") {
|
||||
for (var u in oldUserData) {
|
||||
if (userList.users.indexOf(u) === -1) {
|
||||
notify(-1, oldUserData[u].name);
|
||||
delete oldUserData[u];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update the "oldUserData" object and notify for new users and names changed
|
||||
if (typeof newdata === "undefined") { return; }
|
||||
if (typeof oldUserData === "undefined") {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
if (readOnly === 0 && !oldUserData[myUserName]) {
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
return;
|
||||
}
|
||||
for (var k in newdata) {
|
||||
if (k !== myUserName && userList.users.indexOf(k) !== -1) {
|
||||
if (typeof oldUserData[k] === "undefined") {
|
||||
notify(1, newdata[k].name);
|
||||
} else if (oldUserData[k].name !== newdata[k].name) {
|
||||
notify(0, newdata[k].name, oldUserData[k].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
oldUserData = JSON.parse(JSON.stringify(newdata));
|
||||
});
|
||||
}
|
||||
|
||||
var ks = function () {
|
||||
if (connected) { kickSpinner(spinner, false); }
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
#pad-iframe {
|
||||
position:fixed;
|
||||
top:2.5em;
|
||||
top:0px;
|
||||
left:0px;
|
||||
bottom:0px;
|
||||
right:0px;
|
||||
|
|
|
@ -86,6 +86,8 @@ define([
|
|||
|
||||
editor.on('instanceReady', function (Ckeditor) {
|
||||
var $bar = $('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox');
|
||||
var parsedHash = Cryptpad.parsePadUrl(window.location.href);
|
||||
var defaultName = Cryptpad.getDefaultName(parsedHash);
|
||||
|
||||
if (readOnly) {
|
||||
$('#pad-iframe')[0].contentWindow.$('#cke_1_toolbox > .cke_toolbar').hide();
|
||||
|
@ -251,19 +253,20 @@ define([
|
|||
};
|
||||
|
||||
var initializing = true;
|
||||
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 names for all users (mapped with their 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) {
|
||||
if (users.indexOf(userKey) === -1) { delete userList[userKey]; }
|
||||
for (var userKey in userData) {
|
||||
if (users.indexOf(userKey) === -1) { 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -291,7 +294,7 @@ define([
|
|||
myData[myID] = {
|
||||
name: myUserName
|
||||
};
|
||||
addToUserList(myData);
|
||||
addToUserData(myData);
|
||||
Cryptpad.setAttribute('username', newName, function (err, data) {
|
||||
if (err) {
|
||||
console.error("Couldn't set username");
|
||||
|
@ -319,13 +322,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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -346,12 +346,11 @@ define([
|
|||
var hjson = Hyperjson.fromDOM(dom, isNotMagicLine, brFilter);
|
||||
hjson[3] = {
|
||||
metadata: {
|
||||
users: userList,
|
||||
users: userData,
|
||||
defaultTitle: defaultName
|
||||
}
|
||||
};
|
||||
if (!isDefaultTitle()) {
|
||||
hjson[3].metadata.title = document.title;
|
||||
}
|
||||
hjson[3].metadata.title = document.title;
|
||||
return stringify(hjson);
|
||||
};
|
||||
|
||||
|
@ -397,17 +396,24 @@ 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;
|
||||
}
|
||||
$bar.find('.' + Toolbar.constants.title).find('span').text(newTitle);
|
||||
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 hjson = JSON.parse(shjson);
|
||||
|
@ -416,9 +422,12 @@ define([
|
|||
if (peerMetadata.metadata.users) {
|
||||
var userData = peerMetadata.metadata.users;
|
||||
// Update the local user data
|
||||
addToUserList(userData);
|
||||
addToUserData(userData);
|
||||
}
|
||||
if (peerMetadata.metadata.title) {
|
||||
if (peerMetadata.metadata.defaultTitle) {
|
||||
updateDefaultTitle(peerMetadata.metadata.defaultTitle);
|
||||
}
|
||||
if (typeof peerMetadata.metadata.title !== "undefined") {
|
||||
updateTitle(peerMetadata.metadata.title);
|
||||
}
|
||||
}
|
||||
|
@ -522,15 +531,20 @@ define([
|
|||
};
|
||||
|
||||
var onInit = realtimeOptions.onInit = function (info) {
|
||||
toolbarList = info.userList;
|
||||
userList = info.userList;
|
||||
var config = {
|
||||
userData: userList,
|
||||
userData: userData,
|
||||
readOnly: readOnly,
|
||||
ifrw: ifrw,
|
||||
onRename: renameCb
|
||||
title: {
|
||||
onRename: renameCb,
|
||||
defaultName: defaultName,
|
||||
suggestName: suggestName
|
||||
},
|
||||
common: Cryptpad
|
||||
};
|
||||
if (readOnly) {delete config.changeNameID; }
|
||||
toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
|
||||
toolbar = info.realtime.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);
|
||||
|
@ -549,8 +563,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 */
|
||||
|
@ -563,8 +577,8 @@ define([
|
|||
$rightside.append($import);
|
||||
|
||||
/* add a rename button */
|
||||
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 */
|
||||
|
@ -597,8 +611,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);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -631,16 +644,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);
|
||||
realtimeOptions.onLocal();
|
||||
module.$userNameButton.click();
|
||||
}
|
||||
realtimeOptions.onLocal();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
#iframe-container {
|
||||
position: fixed;
|
||||
top: 2.6em;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
|
|
|
@ -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,
|
||||
|
@ -149,21 +152,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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -205,12 +209,11 @@ define([
|
|||
var obj = {
|
||||
content: textValue,
|
||||
metadata: {
|
||||
users: userList
|
||||
users: userData,
|
||||
defaultTitle: defaultName
|
||||
}
|
||||
};
|
||||
if (!isDefaultTitle()) {
|
||||
obj.metadata.title = APP.title;
|
||||
}
|
||||
obj.metadata.title = APP.title;
|
||||
if (textColor) {
|
||||
obj.metadata.color = textColor;
|
||||
}
|
||||
|
@ -248,7 +251,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");
|
||||
|
@ -286,13 +289,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 (APP.title === defaultName) {
|
||||
return getHeadingText() || "";
|
||||
} else {
|
||||
return APP.title || getHeadingText() || name;
|
||||
return APP.title || getHeadingText() || defaultName;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -344,7 +344,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 +352,10 @@ define([
|
|||
setTabTitle();
|
||||
return;
|
||||
}
|
||||
APP.title = data;
|
||||
setTabTitle();
|
||||
$bar.find('.' + Toolbar.constants.title).find('span.title').text(data);
|
||||
$bar.find('.' + Toolbar.constants.title).find('input').val(data);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -369,6 +373,11 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -376,22 +385,37 @@ define([
|
|||
if (json.metadata.users) {
|
||||
var userData = json.metadata.users;
|
||||
// Update the local user data
|
||||
addToUserList(userData);
|
||||
addToUserData(userData);
|
||||
}
|
||||
if (json.metadata.title) {
|
||||
if (json.metadata.defaultTitle) {
|
||||
updateDefaultTitle(json.metadata.defaultTitle);
|
||||
}
|
||||
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;
|
||||
userList = info.userList;
|
||||
var config = {
|
||||
userData: userList,
|
||||
userData: userData,
|
||||
readOnly: readOnly,
|
||||
ifrw: $('#pad-iframe')[0].contentWindow
|
||||
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);
|
||||
|
@ -413,8 +437,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,14 +451,8 @@ 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);
|
||||
//var $setTitle = Cryptpad.createButton('rename', true, {suggestName: suggestName}, renameCb);
|
||||
//$rightside.append($setTitle);
|
||||
}
|
||||
|
||||
/* add a forget button */
|
||||
|
@ -576,14 +594,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);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -662,16 +673,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();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue