Improve the toolbar style and the way the userlist is displayed

This commit is contained in:
yflory 2016-10-12 18:40:26 +02:00
parent d2389a5729
commit 24fbe22c9d
15 changed files with 618 additions and 311 deletions

View File

@ -13,7 +13,7 @@ define([
$.ajax({
url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html',
success: function (ret) {
$('iframe').height('96%');
//:$('iframe').height('96%');
$('body').append(ret);
LS.main();
Messages._applyTranslation();

View File

@ -16,8 +16,6 @@
color: #666;
font-weight: bold;
height: 30px;
margin-bottom: -3px;
display: inline-block;
width: 100%;
z-index: 9001;
@ -39,20 +37,40 @@
}
}
button {
button, .rightside-element {
height: 26px;
padding-right: 5px;
padding-left: 5px;
margin: 2px;
}
button {
background-color: inherit;
background-image: linear-gradient(to bottom,#fff,#e4e4e4);
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
border-radius: 3px;
margin-right: 5px;
padding-right: 5px;
padding-left: 5px;
&:hover {
background-image:linear-gradient(to bottom,#f2f2f2,#ccc);
}
&.userlist {
@media screen and (max-width: 800px) {
display: none;
}
@media screen and (min-width: 801px) {
display: inline-block;
}
&.small {
@media screen and (max-width: 800px) {
display: inline-block;
}
@media screen and (min-width: 801px) {
display: none;
}
}
}
}
.rightside-button {
float: right;
cursor: pointer;
@ -63,18 +81,47 @@
float: left;
}
.rightside-element {
vertical-align: middle;
white-space: nowrap;
//float: right;
}
select {
border: 0px;
margin-left: 5px;
margin-right: 5px;
padding-left: 5px;
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
}
}
.cryptpad-toolbar-leftside {
float: left;
div {
float: left;
max-width: 35%;
.cryptpad-dropdown-container {
position: relative;
display: inline-block;
padding: 0px;
.cryptpad-dropdown {
z-index:1000;
display:none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
height: auto;
p {
width: 210px;
padding: 0;
margin: 0;
}
}
}
.cryptpad-userbuttons-container {
display: none;
}
}
@ -87,6 +134,7 @@
}
.cryptpad-spinner {
float: left;
display: inline-block;
}
.cryptpad-readonly {
margin-right: 20px;
@ -94,13 +142,12 @@
text-transform: uppercase;
}
.cryptpad-toolbar-username {
font-style: italic;
}
.lag {
display: inline-block;
vertical-align: middle;
padding: 0 !important;
margin: 0 !important;
margin: 0 5px !important;
height: 15px !important;
width: 15px !important;
border-radius: 50%;

View File

@ -16,8 +16,6 @@
user-select: none;
color: #666;
font-weight: bold;
height: 30px;
margin-bottom: -3px;
display: inline-block;
width: 100%;
z-index: 9001;
@ -37,20 +35,43 @@
cursor: pointer;
color: #000;
}
.cryptpad-toolbar button {
.cryptpad-toolbar button,
.cryptpad-toolbar .rightside-element {
height: 26px;
padding-right: 5px;
padding-left: 5px;
margin: 2px;
}
.cryptpad-toolbar button {
background-color: inherit;
background-image: linear-gradient(to bottom, #fff, #e4e4e4);
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
border-radius: 3px;
margin-right: 5px;
padding-right: 5px;
padding-left: 5px;
}
.cryptpad-toolbar button:hover {
background-image: linear-gradient(to bottom, #f2f2f2, #ccc);
}
@media screen and (max-width: 800px) {
.cryptpad-toolbar button.userlist {
display: none;
}
}
@media screen and (min-width: 801px) {
.cryptpad-toolbar button.userlist {
display: inline-block;
}
}
@media screen and (max-width: 800px) {
.cryptpad-toolbar button.userlist.small {
display: inline-block;
}
}
@media screen and (min-width: 801px) {
.cryptpad-toolbar button.userlist.small {
display: none;
}
}
.cryptpad-toolbar .rightside-button {
float: right;
cursor: pointer;
@ -59,17 +80,44 @@
cursor: pointer;
float: left;
}
.cryptpad-toolbar .rightside-element {
vertical-align: middle;
white-space: nowrap;
}
.cryptpad-toolbar select {
border: 0px;
margin-left: 5px;
margin-right: 5px;
padding-left: 5px;
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
}
.cryptpad-toolbar-leftside {
float: left;
max-width: 35%;
}
.cryptpad-toolbar-leftside div {
float: left;
.cryptpad-toolbar-leftside .cryptpad-dropdown-container {
position: relative;
display: inline-block;
padding: 0px;
}
.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown {
z-index: 1000;
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
height: auto;
}
.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p {
width: 210px;
padding: 0;
margin: 0;
}
.cryptpad-toolbar-leftside .cryptpad-userbuttons-container {
display: none;
}
.cryptpad-toolbar-rightside {
text-align: right;
@ -79,20 +127,18 @@
}
.cryptpad-spinner {
float: left;
display: inline-block;
}
.cryptpad-readonly {
margin-right: 20px;
font-weight: bold;
text-transform: uppercase;
}
.cryptpad-toolbar-username {
font-style: italic;
}
.lag {
display: inline-block;
vertical-align: middle;
padding: 0 !important;
margin: 0 !important;
margin: 0 5px !important;
height: 15px !important;
width: 15px !important;
border-radius: 50%;

View File

@ -22,7 +22,7 @@ define(function () {
out.reconnecting = 'Reconnexion...';
out.lag = 'Latence';
out.readonly = 'Lecture seule';
out.anonymous = "Vous êtes actuellement anonyme";
out.anonymous = "nonyme";
out.yourself = "Vous-même";
out.anonymousUsers = "utilisateurs anonymes";
out.anonymousUser = "utilisateur anonyme";
@ -78,7 +78,14 @@ 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 = "en édition";
out.viewing = "en lecture";
out.editShare = "Partager l'URL";
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.disconnectAlert = 'Perte de la connexion au réseau !';

View File

@ -22,7 +22,7 @@ define(function () {
out.reconnecting = 'Reconnecting...';
out.lag = 'Lag';
out.readonly = 'Read only';
out.anonymous = "You are currently anonymous";
out.anonymous = "Anonymous";
out.yourself = "Yourself";
out.anonymousUsers = "anonymous users";
out.anonymousUser = "anonymous user";
@ -79,6 +79,14 @@ 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.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.disconnectAlert = 'Network connection lost!';

View File

@ -19,23 +19,35 @@
html, body {
overflow-y: hidden;
}
#iframe-container {
position: fixed;
top: 2.5em;
bottom: 0px;
right: 0px;
left: 0px;
padding: 0px;
}
#pad-iframe {
position:fixed;
top:2.5em;
left:0px;
bottom:0px;
right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
box-sizing: border-box;
}
/* We use !important here to override the 96% set to the element in DecorateToolbar.js
when we enter fullscreen mode. It allows us to avoid changing the iframe's size in JS */
#pad-iframe.fullscreen {
top: 0px;
height: 100% !important;
}
</style>
</head>
<body>
<iframe id="pad-iframe" src="inner.html"></iframe>
<div id="iframe-container">
<iframe id="pad-iframe" src="inner.html"></iframe>
</div>
</body>
</html>

View File

@ -31,24 +31,24 @@
<script src="/bower_components/codemirror/addon/fold/markdown-fold.js"></script>
<script src="/bower_components/codemirror/addon/fold/comment-fold.js"></script>
<style>
html {
height: 100%;
html, body{
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
overflow: hidden;
box-sizing: border-box;
position: relative;
}
body {
height: 100%;
margin: 0px;
display: flex;
flex-flow: column;
}
.CodeMirror {
position: absolute;
top: 25px;
bottom: 0px;
left: 0px;
right: 0px;
height: auto;
height: 100%;
}
#cme_toolbox {
font: 12px Arial,Helvetica,Tahoma,Verdana,sans-serif;
height: 25px;
background: -webkit-linear-gradient(#EEEEEE, #DADADA); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(white, #DDDDDD); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(white, #DDDDDD); /* For Firefox 3.6 to 15 */

View File

@ -309,6 +309,9 @@ define([
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username);
var $editShare = $bar.find('.' + Toolbar.constants.editShare);
var $viewShare = $bar.find('.' + Toolbar.constants.viewShare);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
@ -322,8 +325,8 @@ define([
var usernameCb = function (newName) {
setName (newName);
};
var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb);
$rightside.append($username);
var $username = Cryptpad.createButton('username', false, {lastName: lastName}, usernameCb);
$userBlock.append($username);
});
/* add an export button */
@ -353,10 +356,18 @@ define([
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
if (!readOnly && viewHash) {
if (!readOnly) {
var $links = Cryptpad.createButton('editshare', false, {editHash: editHash});
$editShare.append($links);
}
if (viewHash) {
/* add a 'links' button */
var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash});
$rightside.append($links);
var $links = Cryptpad.createButton('viewshare', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
if (!readOnly) {
var $links = Cryptpad.createButton('viewopen', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
}
}
var configureLanguage = function (cb) {

View File

@ -716,10 +716,8 @@ define([
break;
case 'username':
button = $('<button>', {
title: Messages.userButton + '\n' + Messages.userButtonTitle,
'class': "fa fa-user",
style: 'font:'+size+' FontAwesome'
});
title: Messages.userButton + '\n' + Messages.userButtonTitle
}).html('<span class="fa fa-user" style="font-family:FontAwesome;"></span>');
if (data && typeof data.lastName !== "undefined" && callback) {
var lastName = data.lastName;
button.click(function() {
@ -729,7 +727,7 @@ define([
});
}
break;
case 'readonly':
/*case 'readonly':
button = $('<button>', {
title: Messages.getViewButton + '\n' + Messages.getViewButtonTitle,
'class': "fa fa-eye",
@ -767,6 +765,59 @@ define([
if (callback) { callback(); }
});
}
break;*/
case 'editshare':
button = $('<button>', {
title: Messages.editShareTitle,
'class': "button action"
}).text(Messages.editShare);
if (data && data.editHash) {
var editHash = data.editHash;
button.click(function () {
var baseUrl = window.location.origin + window.location.pathname + '#';
var url = baseUrl + editHash;
var success = Clipboard.copy(url);
if (success) {
common.log(Messages.shareSuccess);
common.findOKButton().click();
return;
}
});
}
break;
case 'viewshare':
button = $('<button>', {
title: Messages.viewShareTitle,
'class': "button action"
}).text(Messages.viewShare);
if (data && data.viewHash) {
var viewHash = data.viewHash;
button.click(function () {
var baseUrl = window.location.origin + window.location.pathname + '#';
var url = baseUrl + viewHash;
var success = Clipboard.copy(url);
if (success) {
common.log(Messages.shareSuccess);
common.findOKButton().click();
return;
}
});
}
break;
case 'viewopen':
button = $('<button>', {
title: Messages.viewOpenTitle,
'class': "button action"
}).text(Messages.viewOpen);
if (data && data.viewHash) {
var viewHash = data.viewHash;
button.click(function () {
var baseUrl = window.location.origin + window.location.pathname + '#';
var url = baseUrl + viewHash;
common.findOKButton().click();
window.open(url);
});
}
break;
case 'present':
button = $('<button>', {

View File

@ -23,9 +23,19 @@ define([
var SPINNER_CLS = Bar.constants.spinner = 'cryptpad-spinner';
var STATE_CLS = Bar.constants.state = 'cryptpad-state';
var USERNAME_CLS = Bar.constants.username = 'cryptpad-toolbar-username';
var READONLY_CLS = Bar.constants.readonly = 'cryptpad-readonly';
var USERBUTTONS_CONTAINER_CLS = Bar.constants.userButtonsContainer = "cryptpad-userbuttons-container";
var USERLIST_CLS = Bar.constants.userlist = "cryptpad-dropdown-users";
var EDITSHARE_CLS = Bar.constants.editShare = "cryptpad-dropdown-editShare";
var VIEWSHARE_CLS = Bar.constants.viewShare = "cryptpad-dropdown-viewShare";
var DROPDOWN_CONTAINER_CLS = Bar.constants.dropdownContainer = "cryptpad-dropdown-container";
var DROPDOWN_CLS = Bar.constants.dropdown = "cryptpad-dropdown";
/** Key in the localStore which indicates realtime activity should be disallowed. */
// TODO remove? will never be used in cryptpad
var LOCALSTORAGE_DISALLOW = Bar.constants.localstorageDisallow = 'cryptpad-disallow';
@ -85,11 +95,72 @@ define([
}, SPINNER_DISAPPEAR_TIME);
};
var createUserList = function ($container) {
var createUserButtons = function ($userlistElement, readOnly) {
var $listElement = $('<span>', {
id: 'userButtons',
'class': USERBUTTONS_CONTAINER_CLS
}).appendTo($userlistElement);
var $editIcon = $('<button>', {
'class': 'userlist dropbtn edit',
title: Messages.editUsersIcon
});
var $editIconSmall = $editIcon.clone().addClass('small');
var $viewIcon = $('<button>', {
'class': 'userlist dropbtn view',
title: Messages.viewUsersIcon
});
var $viewIconSmall = $viewIcon.clone().addClass('small');
var $dropdownEditUsers = $('<p>', {'class': USERLIST_CLS});
var $dropdownEditShare = $('<p>', {'class': EDITSHARE_CLS});
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});
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')) {
$elmt.hide();
return;
}
$userlistElement.find('.' + DROPDOWN_CLS).hide();
$elmt.show();
};
};
$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);
}
};
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);
createUserButtons($userlist, readOnly);
$container.append($userlist);
return $userlist[0];
};
@ -120,60 +191,72 @@ define([
if (n === 1) { return '; + ' + Messages.oneViewer; }
return '; + ' + Messages._getKey('viewers', [n]);
};
var updateUserList = function (myUserName, listElement, userList, userData, readOnly) {
var updateUserList = function (myUserName, userlistElement, userList, userData, readOnly, $stateElement) {
var meIdx = userList.indexOf(myUserName);
if (meIdx === -1) {
listElement.textContent = Messages.synchronizing;
$stateElement.text(Messages.synchronizing);
return;
}
$stateElement.text('');
// Make sure the user block 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.
userList = readOnly === -1 ? userList : arrayIntersect(userList, Object.keys(userData));
var innerHTML;
var numberOfViewUsers = numberOfUsers - userList.length;
// Names of editing users
var editUsersNames = getOtherUsers(myUserName, userList, userData);
var editTitle = Messages.editUsersIcon;
// Number of anonymous editing users
var anonymous = numberOfUsers - editUsersNames.length;
// Display the user list in the title property of the "edit users" icon.
// Update the userlist
var editUsersList = '';
if (readOnly === 0) {
editTitle += '\n' + Messages.yourself;
editUsersNames.unshift(Messages.yourself);
anonymous--;
}
if (editUsersNames.length > 0) {
editTitle += '\n' + editUsersNames.join('\n');
}
if (anonymous > 0) {
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
editTitle += '\n' + anonymous + " " + text;
editUsersNames.push(anonymous + " " + text);
}
if (editUsersNames.length > 0) {
editUsersList += editUsersNames.join('<br>');
}
$userButtons.find('.' + USERLIST_CLS).html(editUsersList);
// Update the buttons
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 $editIcon = $('<button>', {
'class': 'fa fa-users',
style: 'font-family: FontAwesome;',
title: editTitle
}).text(' ' + userList.length + ' people editing');
var $viewIcon = $('<span>', {
disabled: 'disabled',
'class': 'fa fa-eye',
style: 'font-family: FontAwesome',
title: Messages.viewUsersIcon
}).text(' ' + numberOfViewUsers + ' people viewing');
var innerHTML;
if (readOnly === 1) {
innerHTML = '<span class="' + READONLY_CLS + '">' + Messages.readonly + '</span>';
// TODO
$userElement.html('<span class="' + READONLY_CLS + '">' + Messages.readonly + '</span>');
}
else {
var name = userData[myUserName] && userData[myUserName].name;
var icon = '<span class="fa fa-user" style="font-family:FontAwesome;"></span>';
if (!name) {
name = '<span title="' + Messages.anonymous + '" class="fa fa-user-secret" style="font-family:FontAwesome"></span>';
name = Messages.anonymous;
}
innerHTML = '<span class="' + USERNAME_CLS + '">' + name + '</span> | ';
$userElement.find("button").html(icon + ' ' + name);
}
innerHTML += $('<div>').append($editIcon).html();
if (readOnly !== -1) {
innerHTML += ' | ' + $('<div>').append($viewIcon).html();
}
listElement.innerHTML = innerHTML;
};
var createLagElement = function ($container) {
@ -181,7 +264,7 @@ define([
'class': LAG_ELEM_CLS,
id: uid(),
});
$container.append($lag);
$container.before($lag);
return $lag[0];
};
@ -215,18 +298,28 @@ define([
};
var create = Bar.create = function ($container, myUserName, realtime, getLag, userList, config) {
var readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1;
var toolbar = createRealtimeToolbar($container);
var userListElement = createUserList(toolbar.find('.' + LEFTSIDE_CLS));
var userListElement = createUserList(toolbar.find('.' + LEFTSIDE_CLS), readOnly);
var spinner = createSpinner(toolbar.find('.' + RIGHTSIDE_CLS));
var lagElement = createLagElement(toolbar.find('.' + RIGHTSIDE_CLS));
var userData = config.userData;
// readOnly = 1 (readOnly enabled), 0 (disabled), -1 (old pad without readOnly mode)
var readOnly = (typeof config.readOnly !== "undefined") ? (config.readOnly ? 1 : 0) : -1;
var saveElement;
var loadElement;
var $stateElement = $(userListElement).find('.' + STATE_CLS);
var connected = false;
if (config.ifrw) {
$(config.ifrw).on('click', function (e) {
if (!e.target.matches('.dropbtn') && !e.target.parentElement.matches('.dropbtn')) {
$container.find('.cryptpad-dropdown').hide();
}
});
}
userList.onChange = function(newUserData) {
var users = userList.users;
if (users.indexOf(myUserName) !== -1) { connected = true; }
@ -234,7 +327,7 @@ define([
if(newUserData) { // Someone has changed his name/color
userData = newUserData;
}
updateUserList(myUserName, userListElement, users, userData, readOnly);
updateUserList(myUserName, userListElement, users, userData, readOnly, $stateElement);
};
var ks = function () {
@ -254,13 +347,13 @@ define([
return {
failed: function () {
connected = false;
userListElement.textContent = Messages.disconnected;
$stateElement.text(Messages.disconnected);
checkLag(undefined, lagElement);
},
reconnecting: function (userId) {
myUserName = userId;
connected = false;
userListElement.textContent = Messages.reconnecting;
$stateElement.text(Messages.reconnecting);
checkLag(getLag, lagElement);
},
connected: function () {

View File

@ -516,6 +516,9 @@ define([
toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username);
var $editShare = $bar.find('.' + Toolbar.constants.editShare);
var $viewShare = $bar.find('.' + Toolbar.constants.viewShare);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
@ -530,7 +533,7 @@ define([
setName (newName);
};
var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb);
$rightside.append($username);
$userBlock.append($username);
});
/* add an export button */
@ -560,10 +563,18 @@ define([
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
if (!readOnly && viewHash) {
if (!readOnly) {
var $links = Cryptpad.createButton('editshare', false, {editHash: editHash});
$editShare.append($links);
}
if (viewHash) {
/* add a 'links' button */
var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash});
$rightside.append($links);
var $links = Cryptpad.createButton('viewshare', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
if (!readOnly) {
var $links = Cryptpad.createButton('viewopen', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
}
}
// set the hash

View File

@ -19,18 +19,22 @@
html, body {
overflow-y: hidden;
}
#iframe-container {
position: fixed;
top: 2.5em;
bottom: 0px;
right: 0px;
left: 0px;
padding: 0px;
}
#pad-iframe {
position:fixed;
top:2.5em;
left:0px;
bottom:0px;
right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
box-sizing: border-box;
}
/* We use !important here to override the 96% set to the element in DecorateToolbar.js
when we enter fullscreen mode. It allows us to avoid changing the iframe's size in JS */
@ -38,10 +42,16 @@
top: 0px;
height: 100% !important;
}
</style>
#iframe-container.fullscreen {
top: 0px;
height: 100% !important;
}
</style>
</head>
<body>
<iframe id="pad-iframe" src="inner.html"></iframe>
<div id="iframe-container">
<iframe id="pad-iframe" src="inner.html"></iframe>
</div>
</body>
</html>

View File

@ -41,6 +41,10 @@
box-sizing: border-box;
position: relative;
}
body {
display: flex;
flex-flow: column;
}
#bar > button {
margin: 5px;
}
@ -111,21 +115,11 @@
html {
height: 100%;
}
body {
height: 100%;
margin: 0px;
}
.CodeMirror {
position: absolute;
top: 25px;
bottom: 0px;
left: 0px;
right: 0px;
height: auto;
height: 100%;
}
#cme_toolbox {
font: 12px Arial,Helvetica,Tahoma,Verdana,sans-serif;
height: 25px;
background: -webkit-linear-gradient(#EEEEEE, #DADADA); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(white, #DDDDDD); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(white, #DDDDDD); /* For Firefox 3.6 to 15 */

View File

@ -328,195 +328,6 @@ define([
onLocal();
};
var onInit = config.onInit = function (info) {
var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox');
toolbarList = info.userList;
var config = {
userData: userList,
readOnly: readOnly
};
if (readOnly) {delete config.changeNameID; }
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
if (!readOnly) {
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
}
/* add a "change username" button */
getLastName(function (err, lastName) {
var usernameCb = function (newName) {
setName (newName);
};
var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb);
$rightside.append($username);
});
/* add an export button */
var $export = Cryptpad.createButton('export', true, {}, exportText);
$rightside.append($export);
if (!readOnly) {
/* add an import button */
var $import = Cryptpad.createButton('import', true, {}, importText);
$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);
}
/* add a forget button */
var forgetCb = function (err, title) {
if (err) { return; }
APP.title = title;
setTabTitle();
};
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
if (!readOnly && viewHash) {
/* add a 'links' button */
var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash + '/present'});
$rightside.append($links);
}
var $present = Cryptpad.createButton('present', true)
.click(function () {
enterPresentationMode(true);
});
if (presentMode) {
$present.hide();
}
$rightside.append($present);
var $leavePresent = Cryptpad.createButton('source', true)
.click(leavePresentationMode);
if (!presentMode) {
$leavePresent.hide();
}
$rightside.append($leavePresent);
var $language = $('<span>', {
'style': "margin-right: 10px;"
}).text(Messages.type.slide + " (Markdown)");
$rightside.append($language);
var configureTheme = function () {
/* Remember the user's last choice of theme using localStorage */
var themeKey = 'CRYPTPAD_CODE_THEME';
var lastTheme = localStorage.getItem(themeKey) || 'default';
/* Let the user select different themes */
var $themeDropdown = $('<select>', {
title: 'color theme',
id: 'display-theme',
});
Themes.forEach(function (o) {
$themeDropdown.append($('<option>', {
selected: o.name === lastTheme,
}).val(o.name).text(o.name));
});
$rightside.append($themeDropdown);
var $theme = $bar.find('select#display-theme');
setTheme(lastTheme, $theme);
$theme.on('change', function () {
var theme = $theme.val();
console.log("Setting theme to %s", theme);
setTheme(theme, $theme);
// remember user choices
localStorage.setItem(themeKey, theme);
});
};
var configureColors = function () {
$back = $('<button>', {
id: SLIDE_BACKCOLOR_ID,
'class': 'fa fa-square',
'style': 'font-family: FontAwesome; color: #000;',
title: Messages.backgroundButton + '\n' + Messages.backgroundButtonTitle
});
$text = $('<button>', {
id: SLIDE_COLOR_ID,
'class': 'fa fa-i-cursor',
'style': 'font-family: FontAwesome; font-weight: bold; color: #fff; background: #000;',
title: Messages.colorButton + '\n' + Messages.colorButtonTitle
});
$testColor = $('<input>', { type: 'color', value: '!' });
var $check = $pad.contents().find("#colorPicker_check");
if ($testColor.attr('type') !== "color" || $testColor.val() === '!') { return; } // TODO
$back.on('click', function() {
var $picker = $('<input>', { type: 'color', value: backColor })
.on('change', function() {
updateColors(undefined, this.value);
onLocal();
});
$check.append($picker);
setTimeout(function() {
$picker.click();
}, 0);
});
$text.on('click', function() {
var $picker = $('<input>', { type: 'color', value: textColor })
.on('change', function() {
updateColors(this.value, undefined);
onLocal();
$check.html('');
});
$check.append($picker);
setTimeout(function() {
$picker.click();
}, 0);
});
$rightside.append($back).append($text);
};
configureTheme();
configureColors();
if (presentMode) {
$('#top-bar').hide();
}
// set the hash
if (!window.location.hash || window.location.hash === '#') {
window.location.hash = editHash;
}
Cryptpad.getPadTitle(function (err, title) {
if (err) {
console.log("Unable to get pad title");
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;
}
});
});
};
var updateTitle = function (newTitle) {
if (newTitle === APP.title) { return; }
// Change the title now, and set it back to the old value if there is an error
@ -564,6 +375,209 @@ define([
}
};
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
};
if (readOnly) {delete config.changeNameID; }
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
var $userBlock = $bar.find('.' + Toolbar.constants.username);
var $editShare = $bar.find('.' + Toolbar.constants.editShare);
var $viewShare = $bar.find('.' + Toolbar.constants.viewShare);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
if (!readOnly) {
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
}
/* add a "change username" button */
getLastName(function (err, lastName) {
var usernameCb = function (newName) {
setName (newName);
};
var $username = Cryptpad.createButton('username', false, {lastName: lastName}, usernameCb);
$userBlock.append($username).hide();
});
/* add an export button */
var $export = Cryptpad.createButton('export', true, {}, exportText);
$rightside.append($export);
if (!readOnly) {
/* add an import button */
var $import = Cryptpad.createButton('import', true, {}, importText);
$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);
}
/* add a forget button */
var forgetCb = function (err, title) {
if (err) { return; }
APP.title = title;
setTabTitle();
};
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
if (!readOnly) {
var $links = Cryptpad.createButton('editshare', false, {editHash: editHash});
$editShare.append($links);
}
if (viewHash) {
/* add a 'links' button */
var $links = Cryptpad.createButton('viewshare', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
if (!readOnly) {
var $links = Cryptpad.createButton('viewopen', false, {viewHash: viewHash + '/present'});
$viewShare.append($links);
}
}
var $present = Cryptpad.createButton('present', true)
.click(function () {
enterPresentationMode(true);
});
if (presentMode) {
$present.hide();
}
$rightside.append($present);
var $leavePresent = Cryptpad.createButton('source', true)
.click(leavePresentationMode);
if (!presentMode) {
$leavePresent.hide();
}
$rightside.append($leavePresent);
var configureTheme = function () {
/*var $language = $('<span>', {
'style': "margin-right: 10px;",
'class': 'rightside-element'
}).text("Markdown");
$rightside.append($language);*/
/* Remember the user's last choice of theme using localStorage */
var themeKey = 'CRYPTPAD_CODE_THEME';
var lastTheme = localStorage.getItem(themeKey) || 'default';
/* Let the user select different themes */
var $themeDropdown = $('<select>', {
title: 'color theme',
id: 'display-theme',
'class': 'rightside-element'
});
Themes.forEach(function (o) {
$themeDropdown.append($('<option>', {
selected: o.name === lastTheme,
}).val(o.name).text(o.name));
});
$rightside.append($themeDropdown);
var $theme = $bar.find('select#display-theme');
setTheme(lastTheme, $theme);
$theme.on('change', function () {
var theme = $theme.val();
console.log("Setting theme to %s", theme);
setTheme(theme, $theme);
// remember user choices
localStorage.setItem(themeKey, theme);
});
};
var configureColors = function () {
var $back = $('<button>', {
id: SLIDE_BACKCOLOR_ID,
'class': 'fa fa-square rightside-button',
'style': 'font-family: FontAwesome; color: #000;',
title: Messages.backgroundButton + '\n' + Messages.backgroundButtonTitle
});
var $text = $('<button>', {
id: SLIDE_COLOR_ID,
'class': 'fa fa-i-cursor rightside-button',
'style': 'font-family: FontAwesome; font-weight: bold; color: #fff; background: #000;',
title: Messages.colorButton + '\n' + Messages.colorButtonTitle
});
var $testColor = $('<input>', { type: 'color', value: '!' });
var $check = $pad.contents().find("#colorPicker_check");
if ($testColor.attr('type') !== "color" || $testColor.val() === '!') { return; } // TODO
$back.on('click', function() {
var $picker = $('<input>', { type: 'color', value: backColor })
.on('change', function() {
updateColors(undefined, this.value);
onLocal();
});
$check.append($picker);
setTimeout(function() {
$picker.click();
}, 0);
});
$text.on('click', function() {
var $picker = $('<input>', { type: 'color', value: textColor })
.on('change', function() {
updateColors(this.value, undefined);
onLocal();
$check.html('');
});
$check.append($picker);
setTimeout(function() {
$picker.click();
}, 0);
});
$rightside.append($back).append($text);
};
configureColors();
configureTheme();
if (presentMode) {
$('#top-bar').hide();
}
// set the hash
if (!window.location.hash || window.location.hash === '#') {
window.location.hash = editHash;
}
Cryptpad.getPadTitle(function (err, title) {
if (err) {
console.log("Unable to get pad title");
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;
}
});
});
};
var unnotify = module.unnotify = function () {
if (module.tabNotification &&
typeof(module.tabNotification.cancel) === 'function') {

View File

@ -18,13 +18,6 @@ define([
var $modal;
var $content;
var $pad;
Slide.setModal = function ($m, $c, $p, iframe) {
$modal = Slide.$modal = $m;
$content = Slide.$content = $c;
$pad = Slide.$pad = $p;
ifrw = Slide.ifrw = iframe;
addEvent();
};
Slide.onChange = function (f) {
if (typeof(f) === 'function') {
@ -135,6 +128,7 @@ define([
$pad.contents().find('.cryptpad-present-button').hide();
$pad.contents().find('.cryptpad-source-button').show();
$pad.addClass('fullscreen');
$('#iframe-container').addClass('fullscreen');
$('.top-bar').hide();
return;
}
@ -143,6 +137,7 @@ define([
$pad.contents().find('.cryptpad-present-button').show();
$pad.contents().find('.cryptpad-source-button').hide();
$pad.removeClass('fullscreen');
$('#iframe-container').removeClass('fullscreen');
$('.top-bar').show();
$modal.removeClass('shown');
};
@ -174,7 +169,7 @@ define([
Slide.draw(i);
};
var first = Slide.first = function () {$
var first = Slide.first = function () {
console.log('first');
Slide.lastIndex = Slide.index;
@ -210,7 +205,7 @@ define([
break;
case 35: // end
Slide.last();
break
break;
case 27: // esc
show(false);
break;
@ -220,5 +215,13 @@ define([
});
};
Slide.setModal = function ($m, $c, $p, iframe) {
$modal = Slide.$modal = $m;
$content = Slide.$content = $c;
$pad = Slide.$pad = $p;
ifrw = Slide.ifrw = iframe;
addEvent();
};
return Slide;
});