mirror of https://github.com/xwiki-labs/cryptpad
Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
commit
6e733b1329
|
@ -10,3 +10,4 @@ messages.log
|
|||
.DS_Store
|
||||
www/scratch
|
||||
data
|
||||
npm-debug.log
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
/* Logs are shown to inform the user that something has happened
|
||||
They are only displayed briefly
|
||||
*/
|
||||
@media print {
|
||||
.alertify-logs {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
.alertify-logs > * {
|
||||
padding: 12px 48px;
|
||||
color: #fafafa;
|
||||
|
@ -1000,11 +1005,6 @@ html.cp,
|
|||
.cp #main_other .buttons {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.cp #fileManagerIframe {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.cp .create,
|
||||
.cp .action {
|
||||
display: inline-block;
|
||||
|
@ -1294,196 +1294,6 @@ html.cp,
|
|||
.cp div.realtime #addoption {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
.cp.slide #modal .button {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
opacity: 0.6;
|
||||
display: none;
|
||||
}
|
||||
.cp.slide #modal .button:hover {
|
||||
opacity: 1;
|
||||
display: block !important;
|
||||
}
|
||||
.cp.slide #modal #button_exit {
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
z-index: 9001;
|
||||
}
|
||||
.cp.slide #modal #button_left {
|
||||
left: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
.cp.slide #modal #button_right {
|
||||
right: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
.cp.slide #modal #content p,
|
||||
.cp.slide #modal #content ul,
|
||||
.cp.slide #modal #content ol {
|
||||
font-size: 26px;
|
||||
}
|
||||
.cp.slide #modal #content img {
|
||||
position: relative;
|
||||
min-width: 1%;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
.cp div.modal,
|
||||
.cp div#modal {
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: none;
|
||||
background-color: #000;
|
||||
}
|
||||
.cp div.modal #content,
|
||||
.cp div#modal #content {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
/* center things as much as possible
|
||||
|
||||
margin-top: 50vh;
|
||||
margin-bottom: 50vh;
|
||||
transform: translateY(-50%);
|
||||
|
||||
*/
|
||||
width: 100vw;
|
||||
height: 56.25vw;
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.cp div.modal #content p,
|
||||
.cp div#modal #content p,
|
||||
.cp div.modal #content li,
|
||||
.cp div#modal #content li,
|
||||
.cp div.modal #content pre,
|
||||
.cp div#modal #content pre,
|
||||
.cp div.modal #content code,
|
||||
.cp div#modal #content code {
|
||||
font-size: 2.75vw;
|
||||
line-height: 3.025vw;
|
||||
}
|
||||
.cp div.modal #content h1,
|
||||
.cp div#modal #content h1 {
|
||||
font-size: 5vw;
|
||||
line-height: 5.5vw;
|
||||
}
|
||||
.cp div.modal #content h2,
|
||||
.cp div#modal #content h2 {
|
||||
font-size: 4.2vw;
|
||||
line-height: 4.62vw;
|
||||
}
|
||||
.cp div.modal #content h3,
|
||||
.cp div#modal #content h3 {
|
||||
font-size: 3.6vw;
|
||||
line-height: 3.96vw;
|
||||
}
|
||||
.cp div.modal #content h4,
|
||||
.cp div#modal #content h4 {
|
||||
font-size: 3vw;
|
||||
line-height: 3.3vw;
|
||||
}
|
||||
.cp div.modal #content h5,
|
||||
.cp div#modal #content h5 {
|
||||
font-size: 2.2vw;
|
||||
line-height: 2.42vw;
|
||||
}
|
||||
.cp div.modal #content h6,
|
||||
.cp div#modal #content h6 {
|
||||
font-size: 1.6vw;
|
||||
line-height: 1.76vw;
|
||||
}
|
||||
.cp div.modal #content h1,
|
||||
.cp div#modal #content h1,
|
||||
.cp div.modal #content h2,
|
||||
.cp div#modal #content h2,
|
||||
.cp div.modal #content h3,
|
||||
.cp div#modal #content h3,
|
||||
.cp div.modal #content h4,
|
||||
.cp div#modal #content h4,
|
||||
.cp div.modal #content h5,
|
||||
.cp div#modal #content h5,
|
||||
.cp div.modal #content h6,
|
||||
.cp div#modal #content h6 {
|
||||
color: inherit;
|
||||
}
|
||||
.cp div.modal #content pre > code,
|
||||
.cp div#modal #content pre > code {
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
}
|
||||
.cp div.modal #content ul,
|
||||
.cp div#modal #content ul,
|
||||
.cp div.modal #content ol,
|
||||
.cp div#modal #content ol {
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.cp div.modal .center,
|
||||
.cp div#modal .center {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
margin: auto;
|
||||
border: 1px solid #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
.cp div.modal.shown,
|
||||
.cp div#modal.shown {
|
||||
display: block;
|
||||
}
|
||||
.cp div.modal table,
|
||||
.cp div#modal table {
|
||||
margin: 30px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.cp div.modal table input,
|
||||
.cp div#modal table input {
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
border: 3px solid #fff;
|
||||
}
|
||||
.cp div.modal table tfoot tr td,
|
||||
.cp div#modal table tfoot tr td {
|
||||
z-index: 4000;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cp div.modal #addtime,
|
||||
.cp div#modal #addtime,
|
||||
.cp div.modal #adddate,
|
||||
.cp div#modal #adddate {
|
||||
color: #46E981;
|
||||
border: 1px solid #46E981;
|
||||
padding: 15px;
|
||||
}
|
||||
.cp div.modal #adddate,
|
||||
.cp div#modal #adddate {
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
.cp div.modal #addtime,
|
||||
.cp div#modal #addtime {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
#cors-store {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -132,9 +132,11 @@ define([
|
|||
if (result.proxy && !result.proxy.login_name) {
|
||||
result.proxy.login_name = result.userName;
|
||||
}
|
||||
Cryptpad.whenRealtimeSyncs(result.realtime, function () {
|
||||
Cryptpad.login(result.userHash, result.userName, function () {
|
||||
document.location.href = '/drive/';
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
switch (err) {
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
(function () {
|
||||
var LS_LANG = "CRYPTPAD_LANG";
|
||||
|
||||
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
|
||||
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
|
||||
var getLanguage = function () { return getStoredLanguage() || getBrowserLanguage(); };
|
||||
var language = getLanguage();
|
||||
|
||||
// add your module to this map so it gets used
|
||||
var map = {
|
||||
'fr': 'Français',
|
||||
|
@ -15,6 +10,19 @@ var map = {
|
|||
'pt-br': 'Português do Brasil'
|
||||
};
|
||||
|
||||
var getStoredLanguage = function () { return localStorage.getItem(LS_LANG); };
|
||||
var getBrowserLanguage = function () { return navigator.language || navigator.userLanguage; };
|
||||
var getLanguage = function () {
|
||||
if (getStoredLanguage()) { return getStoredLanguage(); }
|
||||
var l = getBrowserLanguage() || '';
|
||||
if (Object.keys(map).indexOf(l) !== -1) {
|
||||
return l;
|
||||
}
|
||||
// Edge returns 'fr-FR' --> transform it to 'fr' and check again
|
||||
return Object.keys(map).indexOf(l.split('-')[0]) !== -1 ? l.split('-')[0] : 'en';
|
||||
};
|
||||
var language = getLanguage();
|
||||
|
||||
var req = ['/customize/translations/messages.js'];
|
||||
if (language && map[language]) { req.push('/customize/translations/messages.' + language + '.js'); }
|
||||
req.push('/bower_components/jquery/dist/jquery.min.js');
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
They are only displayed briefly
|
||||
*/
|
||||
.alertify-logs {
|
||||
@media print {
|
||||
visibility: hidden;
|
||||
}
|
||||
> * {
|
||||
padding: @padding-base @padding-base * 4;
|
||||
color: @alertify-fore;
|
||||
|
|
|
@ -494,12 +494,6 @@ noscript {
|
|||
}
|
||||
}
|
||||
|
||||
#fileManagerIframe {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
|
||||
.create, .action {
|
||||
|
@ -816,192 +810,6 @@ form.realtime, div.realtime {
|
|||
#adduser { .top-left; }
|
||||
#addoption { .bottom-left; }
|
||||
}
|
||||
|
||||
// used for slides
|
||||
.viewportRatio (@x, @y, @p: 100) {
|
||||
width: @p * 100vw;
|
||||
height: @y * (@p * 100vw) / @x;
|
||||
max-width: @x / @y * (@p * 100vh);
|
||||
max-height: (@p * 100vh);
|
||||
}
|
||||
|
||||
&.slide {
|
||||
#modal {
|
||||
.button {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
opacity: 0.6;
|
||||
display: none;
|
||||
}
|
||||
.button:hover {
|
||||
opacity: 1;
|
||||
display: block !important;
|
||||
}
|
||||
#button_exit {
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
z-index: 9001;
|
||||
}
|
||||
#button_left {
|
||||
left: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
#button_right {
|
||||
right: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
}
|
||||
#modal #content {
|
||||
p, ul, ol { font-size: 26px; }
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
min-width: 1%;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.modal, div#modal {
|
||||
display: none;
|
||||
|
||||
#content {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
|
||||
/* center things as much as possible
|
||||
|
||||
margin-top: 50vh;
|
||||
margin-bottom: 50vh;
|
||||
transform: translateY(-50%);
|
||||
|
||||
*/
|
||||
|
||||
width: 100vw;
|
||||
height: 56.25vw; // height:width ratio = 9/16 = .5625
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh; // 16/9 = 1.778
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top:0;bottom:0; // vertical center
|
||||
left:0;right:0; // horizontal center
|
||||
|
||||
p, li, pre, code {
|
||||
.size(2.75);
|
||||
}
|
||||
|
||||
h1 { .size(5); }
|
||||
h2 { .size(4.2); }
|
||||
h3 { .size(3.6); }
|
||||
h4 { .size (3); }
|
||||
h5 { .size(2.2); }
|
||||
h6 { .size(1.6); }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: none;
|
||||
|
||||
background-color: @slide-default-bg;
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
margin: auto;
|
||||
border: 1px solid @light-base;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 30px;
|
||||
|
||||
border-collapse: collapse;
|
||||
tr {
|
||||
td {
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
border: 3px solid @base;
|
||||
}
|
||||
|
||||
thead {
|
||||
tr {
|
||||
th {
|
||||
span.remove {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
td {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
tfoot {
|
||||
tr {
|
||||
td {
|
||||
z-index: 4000;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#addtime,
|
||||
#adddate {
|
||||
color: @cp-green;
|
||||
border: 1px solid @cp-green;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#adddate { .top-left; }
|
||||
#addtime { .bottom-left; }
|
||||
}
|
||||
}
|
||||
|
||||
// hack for our cross-origin iframe
|
||||
|
|
|
@ -25,6 +25,7 @@ define(function () {
|
|||
|
||||
out.loading = "Chargement...";
|
||||
out.error = "Erreur";
|
||||
out.saved = "Enregistré";
|
||||
|
||||
out.disconnected = 'Déconnecté';
|
||||
out.synchronizing = 'Synchronisation';
|
||||
|
@ -76,6 +77,14 @@ define(function () {
|
|||
out.backgroundButtonTitle = 'Changer la couleur de fond de la présentation';
|
||||
out.colorButtonTitle = 'Changer la couleur du texte en mode présentation';
|
||||
|
||||
out.printButton = "Imprimer";
|
||||
out.printButtonTitle = "Imprimer votre présentation ou l'enregistrer au format PDF";
|
||||
out.printOptions = "Options d'impression";
|
||||
out.printSlideNumber = "Afficher le numéro des slides";
|
||||
out.printDate = "Afficher la date";
|
||||
out.printTitle = "Afficher le titre du pad";
|
||||
out.printCSS = "Personnaliser l'apparence (CSS):";
|
||||
|
||||
out.editShare = "Lien d'édition";
|
||||
out.editShareTitle = "Copier le lien d'édition dans le presse-papiers";
|
||||
out.editOpen = "Éditer dans un nouvel onglet";
|
||||
|
@ -248,6 +257,11 @@ define(function () {
|
|||
out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive";
|
||||
out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles.";
|
||||
|
||||
out.settings_importTitle = "Importer les pads récents de ce navigateur dans mon CryptDrive";
|
||||
out.settings_import = "Importer";
|
||||
out.settings_importConfirm = "Êtes-vous sûr de vouloir importer les pads récents de ce navigateur dans le CryptDrive de votre compte utilisateur ?";
|
||||
out.settings_importDone = "Importation terminée";
|
||||
|
||||
out.settings_userFeedbackHint1 = "CryptPad peut envoyer des retours d'expérience très limités vers le serveur, de manière à nous permettre d'améliorer l'expérience des utilisateurs.";
|
||||
out.settings_userFeedbackHint2 = "Le contenu de vos pads et les clés de déchiffrement ne seront jamais partagés avec le serveur.";
|
||||
out.settings_userFeedback = "Activer l'envoi de retours d'expérience";
|
||||
|
|
|
@ -27,6 +27,7 @@ define(function () {
|
|||
|
||||
out.loading = "Loading...";
|
||||
out.error = "Error";
|
||||
out.saved = "Saved";
|
||||
|
||||
out.disconnected = 'Disconnected';
|
||||
out.synchronizing = 'Synchronizing';
|
||||
|
@ -78,6 +79,14 @@ define(function () {
|
|||
out.backgroundButtonTitle = 'Change the background color in the presentation';
|
||||
out.colorButtonTitle = 'Change the text color in presentation mode';
|
||||
|
||||
out.printButton = "Print";
|
||||
out.printButtonTitle = "Print your slides or export them as a PDF file";
|
||||
out.printOptions = "Print options";
|
||||
out.printSlideNumber = "Display the slide number";
|
||||
out.printDate = "Display the date";
|
||||
out.printTitle = "Display the pad title";
|
||||
out.printCSS = "Custom style rules (CSS):";
|
||||
|
||||
out.editShare = "Editing link";
|
||||
out.editShareTitle = "Copy the editing link to clipboard";
|
||||
out.editOpen = "Open editing link in a new tab";
|
||||
|
@ -93,7 +102,7 @@ define(function () {
|
|||
|
||||
out.okButton = 'OK (enter)';
|
||||
|
||||
out.cancel = "Cancel"; // Not used?
|
||||
out.cancel = "Cancel";
|
||||
out.cancelButton = 'Cancel (esc)';
|
||||
|
||||
// Polls
|
||||
|
@ -250,6 +259,11 @@ define(function () {
|
|||
out.settings_resetTipsButton = "Reset the available tips in CryptDrive";
|
||||
out.settings_resetTipsDone = "All the tips are now visible again.";
|
||||
|
||||
out.settings_importTitle = "Import this browser's recent pads in my CryptDrive";
|
||||
out.settings_import = "Import";
|
||||
out.settings_confirm = "Are you sure you want to import recent pads from this browser to your user account's CryptDrive?";
|
||||
out.settings_done = "Import completed";
|
||||
|
||||
out.settings_userFeedbackHint1 = "CryptPad provides some very basic feedback to the server, to let us know how to improve your experience.";
|
||||
out.settings_userFeedbackHint2 = "Your pad's content will never be shared with the server.";
|
||||
out.settings_userFeedback = "Enable user feedback";
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"scripts": {
|
||||
"lint": "jshint --config .jshintrc --exclude-path .jshintignore .",
|
||||
"test": "node TestSelenium.js",
|
||||
"style": "lessc ./customize.dist/src/less/cryptpad.less > ./customize.dist/main.css && lessc ./customize.dist/src/less/toolbar.less > ./customize.dist/toolbar.css && lessc ./www/drive/file.less > ./www/drive/file.css && lessc ./www/settings/main.less > ./www/settings/main.css",
|
||||
"style": "lessc ./customize.dist/src/less/cryptpad.less > ./customize.dist/main.css && lessc ./customize.dist/src/less/toolbar.less > ./customize.dist/toolbar.css && lessc ./www/drive/file.less > ./www/drive/file.css && lessc ./www/settings/main.less > ./www/settings/main.css && lessc ./www/slide/slide.less > ./www/slide/slide.css",
|
||||
"template": "cd customize.dist/src && node build.js"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
data-main-favicon="/customize/main-favicon.png"
|
||||
data-alt-favicon="/customize/alt-favicon.png"
|
||||
id="favicon" />
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="/customize/main.css" />
|
||||
<style>
|
||||
html, body {
|
||||
|
@ -45,5 +46,14 @@
|
|||
<div id="iframe-container">
|
||||
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
|
||||
</div>
|
||||
<div id="loading">
|
||||
<div class="loadingContainer">
|
||||
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||
<div class="spinnerContainer">
|
||||
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||
</div>
|
||||
<p data-localization="loading"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
define([
|
||||
'/api/config',
|
||||
'/customize/messages.js?app=' + window.location.pathname.split('/').filter(function (x) { return x; }).join('.'),
|
||||
'/customize/fsStore.js',
|
||||
'/common/fsStore.js',
|
||||
'/bower_components/chainpad-crypto/crypto.js?v=0.1.5',
|
||||
'/bower_components/alertifyjs/dist/js/alertify.js',
|
||||
'/bower_components/spin.js/spin.min.js',
|
||||
'/common/clipboard.js',
|
||||
'/customize/fsStore.js',
|
||||
'/customize/application_config.js',
|
||||
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
|
@ -621,6 +620,28 @@ define([
|
|||
};
|
||||
|
||||
// STORAGE
|
||||
var findWeaker = common.findWeaker = function (href, recents) {
|
||||
var rHref = href || getRelativeHref(window.location.href);
|
||||
var parsed = parsePadUrl(rHref);
|
||||
if (!parsed.hash) { return false; }
|
||||
var weaker;
|
||||
recents.some(function (pad) {
|
||||
var p = parsePadUrl(pad.href);
|
||||
if (p.type !== parsed.type) { return; } // Not the same type
|
||||
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
||||
var pHash = parseHash(p.hash);
|
||||
var parsedHash = parseHash(parsed.hash);
|
||||
if (!parsedHash || !pHash) { return; }
|
||||
if (pHash.version !== parsedHash.version) { return; }
|
||||
if (pHash.channel !== parsedHash.channel) { return; }
|
||||
if (pHash.mode === 'view' && parsedHash.mode === 'edit') {
|
||||
weaker = pad.href;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
});
|
||||
return weaker;
|
||||
};
|
||||
var findStronger = common.findStronger = function (href, recents) {
|
||||
var rHref = href || getRelativeHref(window.location.href);
|
||||
var parsed = parsePadUrl(rHref);
|
||||
|
@ -862,12 +883,16 @@ define([
|
|||
return Messages.tips[keys[rdm]];
|
||||
};
|
||||
common.addLoadingScreen = function (loadingText) {
|
||||
var $loading, $container;
|
||||
if ($('#' + LOADING).length) {
|
||||
$('#' + LOADING).show();
|
||||
return;
|
||||
$loading = $('#' + LOADING).show();
|
||||
if (loadingText) {
|
||||
$('#' + LOADING).find('p').text(loadingText);
|
||||
}
|
||||
$container = $loading.find('.loadingContainer');
|
||||
} else {
|
||||
var $loading = $('<div>', {id: LOADING});
|
||||
var $container = $('<div>', {'class': 'loadingContainer'});
|
||||
$container = $('<div>', {'class': 'loadingContainer'});
|
||||
$container.append('<img class="cryptofist" src="/customize/cryptofist_small.png" />');
|
||||
var $spinner = $('<div>', {'class': 'spinnerContainer'});
|
||||
var loadingSpinner = common.spinner($spinner).show();
|
||||
|
@ -875,13 +900,10 @@ define([
|
|||
$container.append($spinner).append($text);
|
||||
$loading.append($container);
|
||||
$('body').append($loading);
|
||||
}
|
||||
if (Messages.tips) {
|
||||
var $loadingTip = $('<div>', {'id': 'loadingTip'});
|
||||
var $tip = $('<span>', {'class': 'tips'}).text(getRandomTip()).appendTo($loadingTip);
|
||||
console.log($('body').height());
|
||||
console.log($container.height());
|
||||
console.log($('body'));
|
||||
console.log($container);
|
||||
$loadingTip.css({
|
||||
'top': $('body').height()/2 + $container.height()/2 + 20 + 'px'
|
||||
});
|
||||
|
|
|
@ -6,10 +6,10 @@ define([
|
|||
|
||||
var Messages = {};
|
||||
|
||||
var ROOT = "root";
|
||||
var UNSORTED = "unsorted";
|
||||
var TRASH = "trash";
|
||||
var TEMPLATE = "template";
|
||||
var ROOT = module.ROOT = "root";
|
||||
var UNSORTED = module.UNSORTED = "unsorted";
|
||||
var TRASH = module.TRASH = "trash";
|
||||
var TEMPLATE = module.TEMPLATE = "template";
|
||||
|
||||
var init = module.init = function (files, config) {
|
||||
var Cryptpad = config.Cryptpad;
|
||||
|
|
|
@ -131,9 +131,10 @@ define([
|
|||
};
|
||||
|
||||
var onReady = function (f, proxy, Cryptpad, exp) {
|
||||
var fo = FO.init(proxy.drive, {
|
||||
var fo = exp.fo = FO.init(proxy.drive, {
|
||||
Cryptpad: Cryptpad
|
||||
});
|
||||
|
||||
//storeObj = proxy;
|
||||
store = initStore(fo, proxy, exp);
|
||||
if (typeof(f) === 'function') {
|
|
@ -0,0 +1,190 @@
|
|||
require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } });
|
||||
define([
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/fileObject.js',
|
||||
'json.sortify'
|
||||
], function (Cryptpad, Crypt, FO, Sortify) {
|
||||
var exp = {};
|
||||
|
||||
var getType = function (el) {
|
||||
if (el === null) { return "null"; }
|
||||
return Array.isArray(el) ? "array" : typeof(el);
|
||||
};
|
||||
|
||||
var findAvailableKey = function (obj, key) {
|
||||
if (typeof (obj[key]) === "undefined") { return key; }
|
||||
var i = 1;
|
||||
var nkey = key;
|
||||
while (typeof (obj[nkey]) !== "undefined") {
|
||||
nkey = key + '_' + i;
|
||||
i++;
|
||||
}
|
||||
return nkey;
|
||||
};
|
||||
|
||||
var copy = function (el) {
|
||||
if (typeof (el) !== "object") { return el; }
|
||||
return JSON.parse(JSON.stringify(el));
|
||||
};
|
||||
|
||||
var deduplicate = function (array) {
|
||||
var a = array.slice();
|
||||
for(var i=0; i<a.length; i++) {
|
||||
for(var j=i+1; j<a.length; j++) {
|
||||
if(a[i] === a[j] || (
|
||||
typeof(a[i]) === "object" && Sortify(a[i]) === Sortify(a[j]))) {
|
||||
a.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
// Merge obj2 into obj1
|
||||
// If keepOld is true, obj1 values are kept in case of conflicti
|
||||
// Not used ATM
|
||||
var merge = function (obj1, obj2, keepOld) {
|
||||
if (typeof (obj1) !== "object" || typeof (obj2) !== "object") { return; }
|
||||
Object.keys(obj2).forEach(function (k) {
|
||||
var v = obj2[k];
|
||||
// If one of them is not an object or if we have a map and a array, don't override, create a new key
|
||||
if (!obj1[k] || typeof(obj1[k]) !== "object" || typeof(obj2[k]) !== "object" ||
|
||||
(getType(obj1[k]) !== getType(obj2[k]))) {
|
||||
// We don't want to override the values in the object (username, preferences)
|
||||
// These values should be the ones stored in the first object
|
||||
if (keepOld) { return; }
|
||||
if (obj1[k] === obj2[k]) { return; }
|
||||
var nkey = findAvailableKey(obj1, k);
|
||||
obj1[nkey] = copy(obj2[k]);
|
||||
return;
|
||||
}
|
||||
// Else, they're both maps or both arrays
|
||||
if (getType(obj1[k]) === "array" && getType(obj2[k]) === "array") {
|
||||
var c = obj1[k].concat(obj2[k]);
|
||||
obj1[k] = deduplicate(c);
|
||||
return;
|
||||
}
|
||||
merge(obj1[k], obj2[k], keepOld);
|
||||
});
|
||||
};
|
||||
|
||||
var createFromPath = function (proxy, oldFo, path, href) {
|
||||
var root = proxy.drive;
|
||||
|
||||
var error = function (msg) {
|
||||
console.error(msg || "Unable to find that path", path);
|
||||
};
|
||||
|
||||
if (path[0] === FO.TRASH && path.length === 4) {
|
||||
href = oldFo.getTrashElementData(path);
|
||||
path.pop();
|
||||
}
|
||||
|
||||
var p, next, nextRoot;
|
||||
path.forEach(function (p, i) {
|
||||
if (!root) { return; }
|
||||
if (typeof(p) === "string") {
|
||||
if (getType(root) !== "object") { root = undefined; error(); return; }
|
||||
if (i === path.length - 1) {
|
||||
root[findAvailableKey(root, p)] = href;
|
||||
return;
|
||||
}
|
||||
next = getType(path[i+1]);
|
||||
nextRoot = getType(root[p]);
|
||||
if (nextRoot !== "undefined") {
|
||||
if (next === "string" && nextRoot === "object" || next === "number" && nextRoot === "array") {
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
p = findAvailableKey(root, p);
|
||||
}
|
||||
if (next === "number") {
|
||||
root[p] = [];
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
root[p] = {};
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
// Path contains a non-string element: it's an array index
|
||||
if (typeof(p) !== "number") { root = undefined; error(); return; }
|
||||
if (getType(root) !== "array") { root = undefined; error(); return; }
|
||||
if (i === path.length - 1) {
|
||||
if (root.indexOf(href) === -1) { root.push(href); }
|
||||
return;
|
||||
}
|
||||
next = getType(path[i+1]);
|
||||
if (next === "number") {
|
||||
error('2 consecutives arrays in the user object');
|
||||
root = undefined;
|
||||
//root.push([]);
|
||||
//root = root[root.length - 1];
|
||||
return;
|
||||
}
|
||||
root.push({});
|
||||
root = root[root.length - 1];
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
var mergeAnonDrive = exp.anonDriveIntoUser = function (proxy, cb) {
|
||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||
if (!localStorage.FS_hash || !Cryptpad.isLoggedIn()) {
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
}
|
||||
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
||||
var todo = function (err, doc) {
|
||||
if (err) { console.error("Cannot migrate recent pads", err); return; }
|
||||
var parsed;
|
||||
try { parsed = JSON.parse(doc); } catch (e) { console.error("Cannot parsed recent pads", e); return; }
|
||||
if (parsed) {
|
||||
//merge(proxy, parsed, true);
|
||||
var oldFo = FO.init(parsed.drive, {
|
||||
Cryptpad: Cryptpad
|
||||
});
|
||||
var newData = Cryptpad.getStore().getProxy();
|
||||
var newFo = newData.fo;
|
||||
var newRecentPads = proxy.drive[Cryptpad.storageKey];
|
||||
var newFiles = newFo.getFilesDataFiles();
|
||||
var oldFiles = oldFo.getFilesDataFiles();
|
||||
oldFiles.forEach(function (href) {
|
||||
// Do not migrate a pad if we already have it, it would create a duplicate in the drive
|
||||
if (newFiles.indexOf(href) !== -1) { return; }
|
||||
// If we have a stronger version, do not add the current href
|
||||
if (Cryptpad.findStronger(href, newRecentPads)) { return; }
|
||||
// If we have a weaker version, replace the href by the new one
|
||||
// NOTE: if that weaker version is in the trash, the strong one will be put in unsorted
|
||||
var weaker = Cryptpad.findWeaker(href, newRecentPads);
|
||||
if (weaker) {
|
||||
// Update RECENTPADS
|
||||
newRecentPads.some(function (pad) {
|
||||
if (pad.href === weaker) {
|
||||
pad.href = href;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
});
|
||||
// Update the file in the drive
|
||||
newFo.replaceHref(weaker, href);
|
||||
return;
|
||||
}
|
||||
// Here it means we have a new href, so we should add it to the drive at its old location
|
||||
var paths = oldFo.findFile(href);
|
||||
if (paths.length === 0) { return; }
|
||||
createFromPath(proxy, oldFo, paths[0], href);
|
||||
// Also, push the file data in our array
|
||||
var data = oldFo.getFileData(href);
|
||||
if (data) {
|
||||
newRecentPads.push(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
};
|
||||
Crypt.get(localStorage.FS_hash, todo);
|
||||
};
|
||||
|
||||
return exp;
|
||||
});
|
|
@ -9,6 +9,7 @@
|
|||
data-main-favicon="/customize/main-favicon.png"
|
||||
data-alt-favicon="/customize/alt-favicon.png"
|
||||
id="favicon" />
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="/customize/main.css" />
|
||||
<script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
|
||||
<style>
|
||||
|
@ -33,5 +34,14 @@
|
|||
</head>
|
||||
<body>
|
||||
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
|
||||
<div id="loading">
|
||||
<div class="loadingContainer">
|
||||
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||
<div class="spinnerContainer">
|
||||
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||
</div>
|
||||
<p data-localization="loading"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -8,8 +8,9 @@ define([
|
|||
'/common/fileObject.js',
|
||||
'/common/toolbar.js',
|
||||
'/customize/application_config.js',
|
||||
'/common/cryptget.js'
|
||||
], function (Listmap, Crypto, TextPatcher, JSONSortify, Cryptpad, FO, Toolbar, AppConfig, Get) {
|
||||
'/common/cryptget.js',
|
||||
'/common/mergeDrive.js'
|
||||
], function (Listmap, Crypto, TextPatcher, JSONSortify, Cryptpad, FO, Toolbar, AppConfig, Get, Merge) {
|
||||
var module = window.MODULE = {};
|
||||
|
||||
var Messages = Cryptpad.Messages;
|
||||
|
@ -2056,26 +2057,12 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
// TODO: move that function and use a more generic API?
|
||||
var migrateAnonDrive = function (proxy, cb) {
|
||||
if (sessionStorage.migrateAnonDrive) {
|
||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||
if (!localStorage.FS_hash || !APP.loggedIn) {
|
||||
Merge.anonDriveIntoUser(proxy, function () {
|
||||
delete sessionStorage.migrateAnonDrive;
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
}
|
||||
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
||||
var todo = function (err, doc) {
|
||||
if (err) { logError("Cannot migrate recent pads", err); return; }
|
||||
var parsed;
|
||||
try { parsed = JSON.parse(doc); } catch (e) { logError("Cannot parsed recent pads", e); }
|
||||
if (parsed) {
|
||||
$.extend(true, proxy, parsed);
|
||||
}
|
||||
delete sessionStorage.migrateAnonDrive;
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
};
|
||||
Get.get(localStorage.FS_hash, todo);
|
||||
});
|
||||
} else {
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ define([
|
|||
if (result.proxy && !result.proxy.login_name) {
|
||||
result.proxy.login_name = result.userName;
|
||||
}
|
||||
|
||||
Cryptpad.whenRealtimeSyncs(result.realtime, function() {
|
||||
Cryptpad.login(result.userHash, result.userName, function () {
|
||||
if (sessionStorage.redirectTo) {
|
||||
var h = sessionStorage.redirectTo;
|
||||
|
@ -89,6 +91,7 @@ define([
|
|||
}
|
||||
window.location.href = '/drive/';
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
switch (err) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<title>CryptPad</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<link rel="icon" type="image/png"
|
||||
href="/customize/main-favicon.png"
|
||||
data-main-favicon="/customize/main-favicon.png"
|
||||
|
@ -56,5 +57,14 @@
|
|||
</head>
|
||||
<body>
|
||||
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
|
||||
<div id="loading">
|
||||
<div class="loadingContainer">
|
||||
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||
<div class="spinnerContainer">
|
||||
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||
</div>
|
||||
<p data-localization="loading"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -143,3 +143,13 @@
|
|||
<button data-localization-title="poll_commit" id="commit"><span class="fa fa-check"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading">
|
||||
<div class="loadingContainer">
|
||||
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||
<div class="spinnerContainer">
|
||||
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||
</div>
|
||||
<p data-localization="loading"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
define([
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/mergeDrive.js',
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
], function (Cryptpad, Crypt) {
|
||||
], function (Cryptpad, Crypt, Merge) {
|
||||
var $ = window.jQuery;
|
||||
var saveAs = window.saveAs;
|
||||
|
||||
|
@ -41,7 +42,7 @@ define([
|
|||
var obj = store.proxy;
|
||||
var $div = $('<div>', {'class': 'infoBlock'});
|
||||
|
||||
var accountName = obj.login_name;
|
||||
var accountName = obj.login_name || localStorage[Cryptpad.userNameKey];
|
||||
var $label = $('<span>', {'class': 'label'}).text(Messages.user_accountName + ':');
|
||||
var $name = $('<span>').text(accountName || '');
|
||||
if (!accountName) {
|
||||
|
@ -65,10 +66,9 @@ define([
|
|||
'id': 'displayName',
|
||||
'placeholder': Messages.anonymous}).appendTo($div);
|
||||
var $save = $('<button>', {'class': 'btn btn-primary'}).text(Messages.settings_save).appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check'}).appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
|
||||
|
||||
$spinner.hide();
|
||||
var displayName = obj[USERNAME_KEY] || '';
|
||||
$input.val(displayName);
|
||||
|
||||
|
@ -135,7 +135,7 @@ define([
|
|||
};
|
||||
var importFile = function (content, file) {
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).appendTo($div);
|
||||
Crypt.put(Cryptpad.getUserHash(), content, function (e) {
|
||||
Crypt.put(Cryptpad.getUserHash() || localStorage[Cryptpad.fileHashKey], content, function (e) {
|
||||
if (e) { console.error(e); }
|
||||
$spinner.remove();
|
||||
});
|
||||
|
@ -187,29 +187,67 @@ define([
|
|||
|
||||
$('<br>').appendTo($div);
|
||||
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved});
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'});
|
||||
|
||||
var $checkbox = $('<input>', {
|
||||
'type': 'checkbox',
|
||||
}).on('change', function () {
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
obj.proxy.allowUserFeedback = $checkbox.is(':checked') || false;
|
||||
// TODO provide feedback to show if this is synced
|
||||
// Cryptpad.whenRealtimeSyncs...
|
||||
Cryptpad.whenRealtimeSyncs(obj.info.realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
});
|
||||
});
|
||||
|
||||
$checkbox.appendTo($div);
|
||||
$label.appendTo($div);
|
||||
|
||||
$ok.hide().appendTo($div);
|
||||
$spinner.hide().appendTo($div);
|
||||
|
||||
if (obj.proxy.allowUserFeedback) {
|
||||
$checkbox[0].checked = true;
|
||||
}
|
||||
return $div;
|
||||
};
|
||||
|
||||
var createImportLocalPads = function (obj) {
|
||||
if (!Cryptpad.isLoggedIn()) { return; }
|
||||
var $div = $('<div>', {'class': 'importLocalPads'});
|
||||
var $label = $('<label>', {'for' : 'importLocalPads'}).text(Messages.settings_importTitle).appendTo($div);
|
||||
$('<br>').appendTo($div);
|
||||
var $button = $('<button>', {'id': 'importLocalPads', 'class': 'btn btn-primary'})
|
||||
.text(Messages.settings_import).appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
|
||||
|
||||
|
||||
$button.click(function () {
|
||||
Cryptpad.confirm(Messages.settings_importConfirm, function (yes) {
|
||||
if (!yes) { return; }
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
Merge.anonDriveIntoUser(obj.proxy, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
Cryptpad.alert(Messages.settings_importDone);
|
||||
});
|
||||
}, undefined, true);
|
||||
});
|
||||
|
||||
return $div;
|
||||
};
|
||||
|
||||
var andThen = function (obj) {
|
||||
APP.$container.append(createTitle());
|
||||
APP.$container.append(createInfoBlock(obj));
|
||||
APP.$container.append(createDisplayNameInput(obj));
|
||||
APP.$container.append(createResetTips());
|
||||
APP.$container.append(createBackupDrive(obj));
|
||||
APP.$container.append(createImportLocalPads(obj));
|
||||
APP.$container.append(createResetDrive(obj));
|
||||
APP.$container.append(createUserFeedbackToggle(obj));
|
||||
obj.proxy.on('change', [], refresh);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
data-main-favicon="/customize/main-favicon.png"
|
||||
data-alt-favicon="/customize/alt-favicon.png"
|
||||
id="favicon" />
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="/customize/main.css" />
|
||||
<style>
|
||||
html, body {
|
||||
|
@ -34,19 +35,30 @@
|
|||
}
|
||||
/* 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 {
|
||||
body #pad-iframe.fullscreen {
|
||||
top: 0px;
|
||||
height: 100% !important;
|
||||
height: 100%;
|
||||
}
|
||||
#iframe-container.fullscreen {
|
||||
body #iframe-container.fullscreen {
|
||||
top: 0px;
|
||||
height: 100% !important;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="iframe-container">
|
||||
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
|
||||
<iframe id="pad-iframe", name="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
|
||||
</div>
|
||||
<div id="loading">
|
||||
<div class="loadingContainer">
|
||||
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||
<div class="spinnerContainer">
|
||||
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||
</div>
|
||||
<p data-localization="loading"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
|
||||
<link rel="stylesheet" href="/customize/main.css">
|
||||
<link rel="stylesheet" href="./slide.css">
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
|
||||
<script src="/bower_components/codemirror/lib/codemirror.js"></script>
|
||||
|
@ -34,55 +35,6 @@
|
|||
<script src="/bower_components/codemirror/addon/fold/markdown-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/fold/comment-fold.js"></script>
|
||||
<script src="/bower_components/codemirror/addon/display/placeholder.js"></script>
|
||||
<style>
|
||||
html, body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
#modal.shown {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 100;
|
||||
background-color: black;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#content h1, h2, h3, h4, h5, h6 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 { font-size: 40px; }
|
||||
h2 { font-size: 37px; }
|
||||
h3 { font-size: 34px; }
|
||||
h4 { font-size: 31px; }
|
||||
h5 { font-size: 27px; }
|
||||
h6 { font-size: 24px; }
|
||||
|
||||
.CodeMirror {
|
||||
height: 100%;
|
||||
}
|
||||
.CodeMirror-focused .cm-matchhighlight {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
#colorPicker_check {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="bar"></div>
|
||||
|
@ -98,6 +50,7 @@
|
|||
<div id="button_right" class="button"><span class="fa fa-chevron-right"></span></div>
|
||||
<div id="content"></div>
|
||||
</div>
|
||||
<div id="print"></div>
|
||||
</span>
|
||||
<div id="nope"></div>
|
||||
<div id="colorPicker_check"></div>
|
||||
|
|
|
@ -136,6 +136,7 @@ define([
|
|||
|
||||
var $modal = $pad.contents().find('#modal');
|
||||
var $content = $pad.contents().find('#content');
|
||||
var $print = $pad.contents().find('#print');
|
||||
|
||||
Slide.setModal($modal, $content, $pad, ifrw, initialState);
|
||||
|
||||
|
@ -411,6 +412,80 @@ define([
|
|||
onLocal();
|
||||
};
|
||||
|
||||
var createPrintDialog = function () {
|
||||
var printOptions = {
|
||||
title: true,
|
||||
slide: true,
|
||||
date: true
|
||||
};
|
||||
|
||||
var $container = $('<div class="alertify">');
|
||||
var $container2 = $('<div class="dialog">').appendTo($container);
|
||||
var $div = $('<div id="printOptions">').appendTo($container2);
|
||||
var $p = $('<p>', {'class': 'msg'}).appendTo($div);
|
||||
$('<b>').text(Messages.printOptions).appendTo($p);
|
||||
$p.append($('<br>'));
|
||||
// Slide number
|
||||
$('<input>', {type: 'checkbox', id: 'checkNumber', checked: 'checked'}).on('change', function () {
|
||||
var c = this.checked;
|
||||
console.log(c);
|
||||
printOptions.slide = c;
|
||||
}).appendTo($p).css('width', 'auto');
|
||||
$('<label>', {'for': 'checkNumber'}).text(Messages.printSlideNumber).appendTo($p);
|
||||
$p.append($('<br>'));
|
||||
// Date
|
||||
$('<input>', {type: 'checkbox', id: 'checkDate', checked: 'checked'}).on('change', function () {
|
||||
var c = this.checked;
|
||||
printOptions.date = c;
|
||||
}).appendTo($p).css('width', 'auto');
|
||||
$('<label>', {'for': 'checkDate'}).text(Messages.printDate).appendTo($p);
|
||||
$p.append($('<br>'));
|
||||
// Title
|
||||
$('<input>', {type: 'checkbox', id: 'checkTitle', checked: 'checked'}).on('change', function () {
|
||||
var c = this.checked;
|
||||
printOptions.title = c;
|
||||
}).appendTo($p).css('width', 'auto');
|
||||
$('<label>', {'for': 'checkTitle'}).text(Messages.printTitle).appendTo($p);
|
||||
$p.append($('<br>'));
|
||||
// CSS
|
||||
$('<label>', {'for': 'cssPrint'}).text(Messages.printCSS).appendTo($p);
|
||||
$p.append($('<br>'));
|
||||
var $textarea = $('<textarea>', {'id':'cssPrint'}).css({'width':'100%', 'height':'100px'}).appendTo($p);
|
||||
|
||||
var fixCSS = function (css) {
|
||||
var append = '.cp #print ';
|
||||
css = css.replace(/(\n*)([^\n]+)\s*\{/g, '$1' + append + '$2 {')
|
||||
return css;
|
||||
};
|
||||
|
||||
var todo = function () {
|
||||
var $style = $('<style>').text(fixCSS($textarea.val()));
|
||||
$print.prepend($style);
|
||||
var length = $print.find('.slide-frame').length;
|
||||
$print.find('.slide-frame').each(function (i, el) {
|
||||
if (printOptions.slide) {
|
||||
$('<div>', {'class': 'slideNumber'}).text((i+1)+'/'+length).appendTo($(el));
|
||||
}
|
||||
if (printOptions.date) {
|
||||
$('<div>', {'class': 'slideDate'}).text(new Date().toLocaleDateString()).appendTo($(el));
|
||||
}
|
||||
if (printOptions.title) {
|
||||
$('<div>', {'class': 'slideTitle'}).text(APP.title).appendTo($(el));
|
||||
}
|
||||
});
|
||||
window.frames["pad-iframe"].focus();
|
||||
window.frames["pad-iframe"].print();
|
||||
$container.remove();
|
||||
};
|
||||
|
||||
var $nav = $('<nav>').appendTo($div);
|
||||
var $ok = $('<button>', {'class': 'ok'}).text(Messages.printButton).appendTo($nav).click(todo);
|
||||
var $cancel = $('<button>', {'class': 'cancel'}).text(Messages.cancel).appendTo($nav).click(function () {
|
||||
$container.remove();
|
||||
});
|
||||
return $container;
|
||||
};
|
||||
|
||||
var onInit = config.onInit = function (info) {
|
||||
userList = info.userList;
|
||||
|
||||
|
@ -466,6 +541,16 @@ define([
|
|||
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
|
||||
$rightside.append($forgetPad);
|
||||
|
||||
var $printButton = $('<button>', {
|
||||
title: Messages.printButtonTitle,
|
||||
'class': 'rightside-button fa fa-print',
|
||||
style: 'font-size: 17px'
|
||||
}).click(function () {
|
||||
$print.html($content.html());
|
||||
$('body').append(createPrintDialog());
|
||||
});
|
||||
$rightside.append($printButton);
|
||||
|
||||
var $present = Cryptpad.createButton('present', true)
|
||||
.click(function () {
|
||||
enterPresentationMode(true);
|
||||
|
@ -628,7 +713,8 @@ define([
|
|||
updateMetadata(userDoc);
|
||||
|
||||
editor.setValue(newDoc || initialState);
|
||||
Slide.update(newDoc);
|
||||
Slide.update(newDoc, true);
|
||||
Slide.draw();
|
||||
|
||||
if (Cryptpad.initialName && APP.title === defaultName) {
|
||||
updateTitle(Cryptpad.initialName);
|
||||
|
|
|
@ -0,0 +1,322 @@
|
|||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 37px;
|
||||
}
|
||||
h3 {
|
||||
font-size: 34px;
|
||||
}
|
||||
h4 {
|
||||
font-size: 31px;
|
||||
}
|
||||
h5 {
|
||||
font-size: 27px;
|
||||
}
|
||||
h6 {
|
||||
font-size: 24px;
|
||||
}
|
||||
body .CodeMirror {
|
||||
height: 100%;
|
||||
}
|
||||
body .CodeMirror-focused .cm-matchhighlight {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
#colorPicker_check {
|
||||
display: block;
|
||||
}
|
||||
@media print {
|
||||
@page {
|
||||
margin: 0;
|
||||
size: auto;
|
||||
}
|
||||
body {
|
||||
display: block;
|
||||
}
|
||||
body .CodeMirror,
|
||||
body #cme_toolbox {
|
||||
display: none;
|
||||
}
|
||||
body * {
|
||||
visibility: hidden;
|
||||
height: auto;
|
||||
max-height: none;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
}
|
||||
html #print {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
}
|
||||
html #print * {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
#print {
|
||||
position: relative;
|
||||
display: none;
|
||||
}
|
||||
#print .slide-frame {
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-flow: column;
|
||||
padding: 5vh 0;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#print .slide-frame li {
|
||||
min-width: 50vw;
|
||||
}
|
||||
#print .slide-frame h1 {
|
||||
padding-top: 0;
|
||||
}
|
||||
#print .slide-frame .slideNumber {
|
||||
position: absolute;
|
||||
right: 5vh;
|
||||
bottom: 5vh;
|
||||
}
|
||||
#print .slide-frame .slideDate {
|
||||
position: absolute;
|
||||
left: 5vh;
|
||||
bottom: 5vh;
|
||||
}
|
||||
#print .slide-frame .slideTitle {
|
||||
position: absolute;
|
||||
top: 5vh;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
.cp.slide #modal .button {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
opacity: 0.6;
|
||||
display: none;
|
||||
}
|
||||
.cp.slide #modal .button:hover {
|
||||
opacity: 1;
|
||||
display: block !important;
|
||||
}
|
||||
.cp.slide #modal #button_exit {
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
z-index: 9001;
|
||||
}
|
||||
.cp.slide #modal #button_left {
|
||||
left: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
.cp.slide #modal #button_right {
|
||||
right: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
.cp.slide #modal #content h1,
|
||||
.cp.slide #modal #content h2,
|
||||
.cp.slide #modal #content h3,
|
||||
.cp.slide #modal #content h4,
|
||||
.cp.slide #modal #content h5,
|
||||
.cp.slide #modal #content h6 {
|
||||
text-align: center;
|
||||
}
|
||||
.cp.slide #modal.shown {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 100;
|
||||
background-color: black;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
.cp.slide #modal #content p,
|
||||
.cp.slide #modal #content ul,
|
||||
.cp.slide #modal #content ol {
|
||||
font-size: 26px;
|
||||
}
|
||||
.cp.slide #modal #content img {
|
||||
position: relative;
|
||||
min-width: 1%;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
.cp div.modal,
|
||||
.cp div#modal {
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: none;
|
||||
background-color: #000;
|
||||
}
|
||||
.cp div.modal #content,
|
||||
.cp div#modal #content {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
/* center things as much as possible
|
||||
|
||||
margin-top: 50vh;
|
||||
margin-bottom: 50vh;
|
||||
transform: translateY(-50%);
|
||||
|
||||
*/
|
||||
width: 100vw;
|
||||
height: 56.25vw;
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.cp div.modal #content p,
|
||||
.cp div#modal #content p,
|
||||
.cp div.modal #content li,
|
||||
.cp div#modal #content li,
|
||||
.cp div.modal #content pre,
|
||||
.cp div#modal #content pre,
|
||||
.cp div.modal #content code,
|
||||
.cp div#modal #content code {
|
||||
font-size: 2.75vw;
|
||||
line-height: 3.025vw;
|
||||
}
|
||||
.cp div.modal #content h1,
|
||||
.cp div#modal #content h1 {
|
||||
font-size: 5vw;
|
||||
line-height: 5.5vw;
|
||||
}
|
||||
.cp div.modal #content h2,
|
||||
.cp div#modal #content h2 {
|
||||
font-size: 4.2vw;
|
||||
line-height: 4.62vw;
|
||||
}
|
||||
.cp div.modal #content h3,
|
||||
.cp div#modal #content h3 {
|
||||
font-size: 3.6vw;
|
||||
line-height: 3.96vw;
|
||||
}
|
||||
.cp div.modal #content h4,
|
||||
.cp div#modal #content h4 {
|
||||
font-size: 3vw;
|
||||
line-height: 3.3vw;
|
||||
}
|
||||
.cp div.modal #content h5,
|
||||
.cp div#modal #content h5 {
|
||||
font-size: 2.2vw;
|
||||
line-height: 2.42vw;
|
||||
}
|
||||
.cp div.modal #content h6,
|
||||
.cp div#modal #content h6 {
|
||||
font-size: 1.6vw;
|
||||
line-height: 1.76vw;
|
||||
}
|
||||
.cp div.modal #content h1,
|
||||
.cp div#modal #content h1,
|
||||
.cp div.modal #content h2,
|
||||
.cp div#modal #content h2,
|
||||
.cp div.modal #content h3,
|
||||
.cp div#modal #content h3,
|
||||
.cp div.modal #content h4,
|
||||
.cp div#modal #content h4,
|
||||
.cp div.modal #content h5,
|
||||
.cp div#modal #content h5,
|
||||
.cp div.modal #content h6,
|
||||
.cp div#modal #content h6 {
|
||||
color: inherit;
|
||||
text-align: center;
|
||||
}
|
||||
.cp div.modal #content pre > code,
|
||||
.cp div#modal #content pre > code {
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
}
|
||||
.cp div.modal #content ul,
|
||||
.cp div#modal #content ul,
|
||||
.cp div.modal #content ol,
|
||||
.cp div#modal #content ol {
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.cp div.modal .center,
|
||||
.cp div#modal .center {
|
||||
position: relative;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
margin: auto;
|
||||
border: 1px solid #ffffff;
|
||||
text-align: center;
|
||||
}
|
||||
.cp div.modal.shown,
|
||||
.cp div#modal.shown {
|
||||
display: block;
|
||||
}
|
||||
.cp div.modal table,
|
||||
.cp div#modal table {
|
||||
margin: 30px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.cp div.modal table input,
|
||||
.cp div#modal table input {
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
border: 3px solid #fff;
|
||||
}
|
||||
.cp div.modal table tfoot tr td,
|
||||
.cp div#modal table tfoot tr td {
|
||||
z-index: 4000;
|
||||
cursor: pointer;
|
||||
}
|
||||
.cp div.modal #addtime,
|
||||
.cp div#modal #addtime,
|
||||
.cp div.modal #adddate,
|
||||
.cp div#modal #adddate {
|
||||
color: #46E981;
|
||||
border: 1px solid #46E981;
|
||||
padding: 15px;
|
||||
}
|
||||
.cp div.modal #adddate,
|
||||
.cp div#modal #adddate {
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
.cp div.modal #addtime,
|
||||
.cp div#modal #addtime {
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
|
@ -19,6 +19,9 @@ define([
|
|||
var $content;
|
||||
var $pad;
|
||||
var placeholder;
|
||||
var separator = '<hr data-pewpew="pezpez">';
|
||||
var separatorReg = /<hr data\-pewpew="pezpez">/g;
|
||||
var slideClass = 'slide-frame';
|
||||
|
||||
Slide.onChange = function (f) {
|
||||
if (typeof(f) === 'function') {
|
||||
|
@ -26,11 +29,15 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
var getNumberOfSlides = Slide.getNumberOfSlides = function () {
|
||||
return $content.find('.' + slideClass).length;
|
||||
};
|
||||
|
||||
var change = function (oldIndex, newIndex) {
|
||||
if (Slide.changeHandlers.length) {
|
||||
Slide.changeHandlers.some(function (f, i) {
|
||||
// HERE
|
||||
f(oldIndex, newIndex, Slide.content.length);
|
||||
f(oldIndex, newIndex, getNumberOfSlides());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -76,7 +83,7 @@ define([
|
|||
var Err;
|
||||
var Els = [A, B].map(function (frag) {
|
||||
if (typeof(frag) === 'object') {
|
||||
if (!frag && frag.body) {
|
||||
if (!frag || (frag && !frag.body)) {
|
||||
Err = "No body";
|
||||
return;
|
||||
}
|
||||
|
@ -108,19 +115,23 @@ define([
|
|||
};
|
||||
|
||||
var draw = Slide.draw = function (i) {
|
||||
console.log("Trying to draw slide #%s", i);
|
||||
if (typeof(Slide.content[i]) !== 'string') { return; }
|
||||
i = i || 0;
|
||||
if (typeof(Slide.content) !== 'string') { return; }
|
||||
|
||||
var c = Slide.content[i];
|
||||
var Dom = domFromHTML('<div id="content">' + Marked(c) + '</div>');
|
||||
var c = Slide.content;
|
||||
var m = '<span class="'+slideClass+'">'+Marked(c).replace(separatorReg, '</span><span class="'+slideClass+'">')+'</span>';
|
||||
|
||||
var Dom = domFromHTML('<div id="content">' + m + '</div>');
|
||||
removeListeners(Dom.body);
|
||||
var patch = makeDiff(domFromHTML($content[0].outerHTML), Dom);
|
||||
|
||||
if (typeof(patch) === 'string') {
|
||||
$content.html(Marked(c));
|
||||
$content.html(m);
|
||||
} else {
|
||||
DD.apply($content[0], patch);
|
||||
}
|
||||
$content.find('.' + slideClass).hide();
|
||||
$content.find('.' + slideClass + ':eq( ' + i + ' )').show();
|
||||
change(Slide.lastIndex, Slide.index);
|
||||
};
|
||||
|
||||
|
@ -159,13 +170,13 @@ define([
|
|||
$modal.removeClass('shown');
|
||||
};
|
||||
|
||||
var update = Slide.update = function (content) {
|
||||
if (!Slide.shown) { return; }
|
||||
if (!content) { content = placeholder; }
|
||||
var old = Slide.content[Slide.index];
|
||||
Slide.content = content.split(/\n\s*\-\-\-\s*\n/).filter(truthy);
|
||||
if (old !== Slide.content[Slide.index]) {
|
||||
draw(Slide.index);
|
||||
var update = Slide.update = function (content, init) {
|
||||
if (!Slide.shown && !init) { return; }
|
||||
if (!content) { content = ''; }
|
||||
var old = Slide.content;
|
||||
Slide.content = content.replace(/\n\s*\-\-\-\s*\n/g, '\n\n'+separator+'\n\n');
|
||||
if (old !== Slide.content) {
|
||||
draw();
|
||||
return;
|
||||
}
|
||||
change(Slide.lastIndex, Slide.index);
|
||||
|
@ -183,7 +194,7 @@ define([
|
|||
console.log('right');
|
||||
Slide.lastIndex = Slide.index;
|
||||
|
||||
var i = Slide.index = Math.min(Slide.content.length -1, Slide.index + 1);
|
||||
var i = Slide.index = Math.min(getNumberOfSlides() -1, Slide.index + 1);
|
||||
Slide.draw(i);
|
||||
};
|
||||
|
||||
|
@ -199,7 +210,7 @@ define([
|
|||
console.log('end');
|
||||
Slide.lastIndex = Slide.index;
|
||||
|
||||
var i = Slide.index = Slide.content.length - 1;
|
||||
var i = Slide.index = getNumberOfSlides() - 1;
|
||||
Slide.draw(i);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
@import "../../customize.dist/src/less/variables.less";
|
||||
@import "../../customize.dist/src/less/mixins.less";
|
||||
|
||||
// used for slides
|
||||
.viewportRatio (@x, @y, @p: 100) {
|
||||
width: @p * 100vw;
|
||||
height: @y * (@p * 100vw) / @x;
|
||||
max-width: @x / @y * (@p * 100vh);
|
||||
max-height: (@p * 100vh);
|
||||
}
|
||||
|
||||
html, body{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
//.cp {
|
||||
h1 { font-size: 40px; }
|
||||
h2 { font-size: 37px; }
|
||||
h3 { font-size: 34px; }
|
||||
h4 { font-size: 31px; }
|
||||
h5 { font-size: 27px; }
|
||||
h6 { font-size: 24px; }
|
||||
|
||||
body {
|
||||
.CodeMirror {
|
||||
height: 100%;
|
||||
}
|
||||
.CodeMirror-focused .cm-matchhighlight {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAFklEQVQI12NgYGBgkKzc8x9CMDAwAAAmhwSbidEoSQAAAABJRU5ErkJggg==);
|
||||
background-position: bottom;
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
}
|
||||
#colorPicker_check {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media print {
|
||||
@page {
|
||||
margin: 0;
|
||||
size: auto;
|
||||
}
|
||||
body {
|
||||
.CodeMirror, #cme_toolbox {
|
||||
display: none;
|
||||
}
|
||||
* {
|
||||
visibility: hidden;
|
||||
height: auto;
|
||||
max-height: none;
|
||||
}
|
||||
display:block;
|
||||
}
|
||||
html, body {
|
||||
max-height: none;
|
||||
overflow: visible;
|
||||
}
|
||||
html {
|
||||
#print {
|
||||
display: block;
|
||||
visibility: visible;
|
||||
* {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#print {
|
||||
position: relative;
|
||||
display: none;
|
||||
.slide-frame {
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-flow: column;
|
||||
padding: 5vh 0;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
li {
|
||||
min-width: 50vw;
|
||||
}
|
||||
h1 {
|
||||
padding-top: 0;
|
||||
}
|
||||
.slideNumber {
|
||||
position: absolute;
|
||||
right: 5vh;
|
||||
bottom: 5vh;
|
||||
}
|
||||
.slideDate {
|
||||
position: absolute;
|
||||
left: 5vh;
|
||||
bottom: 5vh;
|
||||
}
|
||||
.slideTitle {
|
||||
position: absolute;
|
||||
top: 5vh;
|
||||
left: 0px; right: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cp {
|
||||
|
||||
&.slide {
|
||||
#modal {
|
||||
.button {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
font-size: 30px;
|
||||
opacity: 0.6;
|
||||
display: none;
|
||||
}
|
||||
.button:hover {
|
||||
opacity: 1;
|
||||
display: block !important;
|
||||
}
|
||||
#button_exit {
|
||||
left: 20px;
|
||||
top: 20px;
|
||||
z-index: 9001;
|
||||
}
|
||||
#button_left {
|
||||
left: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
#button_right {
|
||||
right: 6vw;
|
||||
bottom: 10vh;
|
||||
}
|
||||
#content {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
}
|
||||
&.shown {
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 100;
|
||||
background-color: black;
|
||||
color: white;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
#modal #content {
|
||||
p, ul, ol { font-size: 26px; }
|
||||
|
||||
img {
|
||||
position: relative;
|
||||
min-width: 1%;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.modal, div#modal {
|
||||
display: none;
|
||||
|
||||
#content {
|
||||
box-sizing: border-box;
|
||||
border: 1px solid white;
|
||||
|
||||
vertical-align: middle;
|
||||
padding: 2.5vw;
|
||||
|
||||
/* center things as much as possible
|
||||
|
||||
margin-top: 50vh;
|
||||
margin-bottom: 50vh;
|
||||
transform: translateY(-50%);
|
||||
|
||||
*/
|
||||
|
||||
width: 100vw;
|
||||
height: 56.25vw; // height:width ratio = 9/16 = .5625
|
||||
max-height: 100vh;
|
||||
max-width: 177.78vh; // 16/9 = 1.778
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top:0;bottom:0; // vertical center
|
||||
left:0;right:0; // horizontal center
|
||||
|
||||
p, li, pre, code {
|
||||
.size(2.75);
|
||||
}
|
||||
|
||||
h1 { .size(5); }
|
||||
h2 { .size(4.2); }
|
||||
h3 { .size(3.6); }
|
||||
h4 { .size (3); }
|
||||
h5 { .size(2.2); }
|
||||
h6 { .size(1.6); }
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: inherit;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
pre > code {
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid #333;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
padding-left: .25vw;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
min-width: 50%;
|
||||
max-width: 100%;
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
box-sizing: border-box;
|
||||
z-index: 9001;
|
||||
position: fixed;
|
||||
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: none;
|
||||
|
||||
background-color: @slide-default-bg;
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
margin: auto;
|
||||
border: 1px solid @light-base;
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 30px;
|
||||
|
||||
border-collapse: collapse;
|
||||
tr {
|
||||
td {
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: 100%;
|
||||
width: 90%;
|
||||
border: 3px solid @base;
|
||||
}
|
||||
|
||||
thead {
|
||||
tr {
|
||||
th {
|
||||
span.remove {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
td {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
tfoot {
|
||||
tr {
|
||||
td {
|
||||
z-index: 4000;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#addtime,
|
||||
#adddate {
|
||||
color: @cp-green;
|
||||
border: 1px solid @cp-green;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
#adddate { .top-left; }
|
||||
#addtime { .bottom-left; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue