Merge branch 'master' into fix-#254
This commit is contained in:
@@ -14,6 +14,7 @@ www/common/hyperscript.js
|
|||||||
www/pad/wysiwygarea-plugin.js
|
www/pad/wysiwygarea-plugin.js
|
||||||
www/pad/mediatag-plugin.js
|
www/pad/mediatag-plugin.js
|
||||||
www/pad/mediatag-plugin-dialog.js
|
www/pad/mediatag-plugin-dialog.js
|
||||||
|
www/pad/disable-base64.js
|
||||||
|
|
||||||
www/kanban/jkanban.js
|
www/kanban/jkanban.js
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
"depthLevel": {
|
"depthLevel": {
|
||||||
"depth": 1 // TODO(cjd) This is obviously not triggering, even with 1
|
"depth": 1 // TODO(cjd) This is obviously not triggering, even with 1
|
||||||
},
|
},
|
||||||
"duplicateProperty": { "enabled": true },
|
"duplicateProperty": { "enabled": false },
|
||||||
"emptyRule": { "enabled": true },
|
"emptyRule": { "enabled": true },
|
||||||
"hexValidation": { "enabled": true }, // disallow actual garbage color hex codes (e.g. #ab)
|
"hexValidation": { "enabled": true }, // disallow actual garbage color hex codes (e.g. #ab)
|
||||||
"propertyUnits": {
|
"propertyUnits": {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
"alertifyjs": "1.0.11",
|
"alertifyjs": "1.0.11",
|
||||||
"scrypt-async": "1.2.0",
|
"scrypt-async": "1.2.0",
|
||||||
"require-css": "0.1.10",
|
"require-css": "0.1.10",
|
||||||
"less": "^2.7.2",
|
"less": "^3.7.1",
|
||||||
"bootstrap": "^v4.0.0",
|
"bootstrap": "^v4.0.0",
|
||||||
"diff-dom": "2.1.1",
|
"diff-dom": "2.1.1",
|
||||||
"nthen": "^0.1.5",
|
"nthen": "^0.1.5",
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
blobStagingPath: './blobstage',
|
blobStagingPath: './blobstage',
|
||||||
|
|
||||||
/* CryptPad's file storage adaptor closes unused files after a configurale
|
/* CryptPad's file storage adaptor closes unused files after a configurable
|
||||||
* number of milliseconds (default 30000 (30 seconds))
|
* number of milliseconds (default 30000 (30 seconds))
|
||||||
*/
|
*/
|
||||||
channelExpirationMs: 30000,
|
channelExpirationMs: 30000,
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ CKEDITOR.editorConfig = function( config ) {
|
|||||||
config.needsBrFiller= fixThings;
|
config.needsBrFiller= fixThings;
|
||||||
config.needsNbspFiller= fixThings;
|
config.needsNbspFiller= fixThings;
|
||||||
|
|
||||||
config.removeButtons= 'Source,Maximize,Anchor';
|
config.removeButtons= 'Source,Maximize';
|
||||||
// magicline plugin inserts html crap into the document which is not part of the
|
// magicline plugin inserts html crap into the document which is not part of the
|
||||||
// document itself and causes problems when it's sent across the wire and reflected back
|
// document itself and causes problems when it's sent across the wire and reflected back
|
||||||
config.removePlugins= 'resize,elementspath';
|
config.removePlugins= 'resize,elementspath';
|
||||||
config.resize_enabled= false; //bottom-bar
|
config.resize_enabled= false; //bottom-bar
|
||||||
config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print';
|
config.extraPlugins= 'autolink,colorbutton,colordialog,font,indentblock,justify,mediatag,print,blockbase64';
|
||||||
config.toolbarGroups= [
|
config.toolbarGroups= [
|
||||||
// {"name":"clipboard","groups":["clipboard","undo"]},
|
// {"name":"clipboard","groups":["clipboard","undo"]},
|
||||||
//{"name":"editing","groups":["find","selection"]},
|
//{"name":"editing","groups":["find","selection"]},
|
||||||
|
|||||||
12
customize.dist/fonts/cptools/fonts/cptools.svg
Normal file
12
customize.dist/fonts/cptools/fonts/cptools.svg
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<metadata>Generated by IcoMoon</metadata>
|
||||||
|
<defs>
|
||||||
|
<font id="cptools" horiz-adv-x="1024">
|
||||||
|
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||||
|
<missing-glyph horiz-adv-x="1024" />
|
||||||
|
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||||
|
<glyph unicode="" glyph-name="template" horiz-adv-x="876" d="M804.244 960h-732.699c-39.513 0-71.545-32.032-71.545-71.545v0-880.909c0-39.513 32.032-71.545 71.545-71.545v0h732.699c39.513 0 71.545 32.032 71.545 71.545v0 880.909c0 39.513-32.032 71.545-71.545 71.545v0zM808.421 7.545c0-2.307-1.87-4.177-4.177-4.177v0h-732.699c-2.307 0-4.177 1.87-4.177 4.177v0 880.909c0 2.307 1.87 4.177 4.177 4.177v0h732.699c2.307 0 4.177-1.87 4.177-4.177v0zM107.789 852.211h660.211v-256h-660.211v256zM107.789 555.789h269.474v-256h-269.474v256zM417.684 70.737h350.316v-26.947h-350.316v26.947zM417.684 133.659h350.316v-26.947h-350.316v26.947zM417.684 196.446h350.316v-26.947h-350.316v26.947zM417.684 259.368h350.316v-26.947h-350.316v26.947zM417.684 555.789h350.316v-26.947h-350.316v26.947zM417.684 498.526h350.316v-26.947h-350.316v26.947zM417.684 441.263h350.316v-26.947h-350.316v26.947zM417.684 384h350.316v-26.947h-350.316v26.947zM417.684 326.737h350.316v-26.947h-350.316v26.947zM107.789 259.368h269.474v-215.579h-269.474v215.579z" />
|
||||||
|
<glyph unicode="" glyph-name="new-template" horiz-adv-x="920" d="M103.696 856.304h635.139v-246.278h-635.139v246.278zM103.696 571.139h259.241v-246.278h-259.241v246.278zM401.823 165.039h337.013v-25.924h-337.013v25.924zM401.823 225.442h337.013v-25.924h-337.013v25.924zM401.823 285.975h337.013v-25.924h-337.013v25.924zM401.823 571.139h337.013v-25.924h-337.013v25.924zM401.823 516.051h337.013v-25.924h-337.013v25.924zM401.823 460.962h337.013v-25.924h-337.013v25.924zM401.823 405.873h337.013v-25.924h-337.013v25.924zM401.823 350.785h337.013v-25.924h-337.013v25.924zM103.696 285.975h259.241v-207.392h-259.241v207.392zM842.532 140.152v751.020c0 38.013-30.816 68.828-68.828 68.828v0h-704.875c-38.013 0-68.828-30.816-68.828-68.828v0-847.457c0-38.013 30.816-68.828 68.828-68.828v0h666.896c19.163-23.765 48.277-38.841 80.912-38.841 57.27 0 103.696 46.426 103.696 103.696 0 48.068-32.706 88.497-77.078 100.248l-0.724 0.163zM68.828 39.696c-2.219 0-4.018 1.799-4.018 4.018v0 847.457c0 2.219 1.799 4.018 4.018 4.018v0h704.875c2.219 0 4.018-1.799 4.018-4.018v0-755.297c-16.886-6.977-31.013-17.69-41.84-31.166l-0.157-0.202h-333.902v-25.924h318.607c-4.743-11.511-7.504-24.874-7.518-38.881v-0.006zM816.608-51.038c-50.111 0-90.734 40.623-90.734 90.734v0c0 0.068 0 0.148 0 0.228 0 14.058 3.253 27.357 9.047 39.184l-0.233-0.526c1.324 3.018 2.711 5.571 4.28 7.995l-0.132-0.218c9.3 15.303 22.547 27.384 38.344 35.021l0.542 0.236c11.301 5.562 24.6 8.814 38.658 8.814 0.080 0 0.16 0 0.241 0h-0.012c50.111 0 90.734-40.623 90.734-90.734s-40.623-90.734-90.734-90.734v0zM861.975 52.658h-32.405v32.405c0 3.579-2.902 6.481-6.481 6.481v0h-12.962c-3.579 0-6.481-2.902-6.481-6.481v0-32.405h-32.405c-3.579 0-6.481-2.902-6.481-6.481v0-12.962c0-3.579 2.902-6.481 6.481-6.481v0h32.405v-32.405c0-3.579 2.902-6.481 6.481-6.481v0h12.962c3.579 0 6.481 2.902 6.481 6.481v0 32.405h32.405c3.579 0 6.481 2.902 6.481 6.481v0 12.962c0 3.579-2.902 6.481-6.481 6.481v0z" />
|
||||||
|
</font></defs></svg>
|
||||||
|
After Width: | Height: | Size: 3.3 KiB |
BIN
customize.dist/fonts/cptools/fonts/cptools.ttf
Normal file
BIN
customize.dist/fonts/cptools/fonts/cptools.ttf
Normal file
Binary file not shown.
BIN
customize.dist/fonts/cptools/fonts/cptools.woff
Normal file
BIN
customize.dist/fonts/cptools/fonts/cptools.woff
Normal file
Binary file not shown.
31
customize.dist/fonts/cptools/style.css
Normal file
31
customize.dist/fonts/cptools/style.css
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'cptools';
|
||||||
|
src:
|
||||||
|
url('fonts/cptools.ttf?dysqmo') format('truetype'),
|
||||||
|
url('fonts/cptools.woff?dysqmo') format('woff'),
|
||||||
|
url('fonts/cptools.svg?dysqmo#cptools') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cptools {
|
||||||
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
|
font-family: 'cptools' !important;
|
||||||
|
speak: none;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
/* Better Font Rendering =========== */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cptools-template:before {
|
||||||
|
content: "\e900";
|
||||||
|
}
|
||||||
|
.cptools-new-template:before {
|
||||||
|
content: "\e901";
|
||||||
|
}
|
||||||
@@ -182,7 +182,7 @@ define([], function () {
|
|||||||
'</div>',
|
'</div>',
|
||||||
'<div class="cp-loading-container">',
|
'<div class="cp-loading-container">',
|
||||||
'<div class="cp-loading-spinner-container">',
|
'<div class="cp-loading-spinner-container">',
|
||||||
'<span class="fa fa-circle-o-notch fa-spin fa-4x fa-fw"></span>',
|
'<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>',
|
||||||
'</div>',
|
'</div>',
|
||||||
'<p id="cp-loading-message"></p>',
|
'<p id="cp-loading-message"></p>',
|
||||||
'</div>'
|
'</div>'
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ define([
|
|||||||
});
|
});
|
||||||
return select;
|
return select;
|
||||||
};
|
};
|
||||||
languageSelector = languageSelector; // jshint
|
|
||||||
|
|
||||||
var footerCol = function (title, L, literal) {
|
var footerCol = function (title, L, literal) {
|
||||||
return h('div.col-6.col-sm-3', [
|
return h('div.col-6.col-sm-3', [
|
||||||
@@ -95,7 +94,7 @@ define([
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
h('div.cp-version-footer', "CryptPad v2.5.0 (Fossa)")
|
h('div.cp-version-footer', "CryptPad v2.6.0 (Gibbon)")
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -633,6 +632,7 @@ define([
|
|||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
|
infopageFooter(),
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
@import (once) './include/font.less';
|
|
||||||
.font_neuropolitical();
|
|
||||||
.font_open-sans();
|
|
||||||
|
|
||||||
body.cp-page-index { @import "./pages/page-index.less"; }
|
|
||||||
body.cp-page-contact { @import "./pages/page-contact.less"; }
|
|
||||||
body.cp-page-login { @import "./pages/page-login.less"; }
|
|
||||||
body.cp-page-register { @import "./pages/page-register.less"; }
|
|
||||||
body.cp-page-what-is-cryptpad { @import "./pages/page-what-is-cryptpad.less"; }
|
|
||||||
body.cp-page-about { @import "./pages/page-about.less"; }
|
|
||||||
body.cp-page-privacy { @import "./pages/page-privacy.less"; }
|
|
||||||
body.cp-page-terms { @import "./pages/page-terms.less"; }
|
|
||||||
|
|
||||||
// Set the HTML style for the apps which shouldn't have a body scrollbar
|
|
||||||
html.cp-app-noscroll {
|
|
||||||
@import "./include/app-noscroll.less";
|
|
||||||
.app-noscroll_main();
|
|
||||||
}
|
|
||||||
// Set the HTML style for printing slides
|
|
||||||
html.cp-app-print {
|
|
||||||
@import "./include/app-print.less";
|
|
||||||
.app-print_main();
|
|
||||||
}
|
|
||||||
|
|
||||||
body.cp-readonly .cp-hidden-if-readonly { display: none !important; }
|
|
||||||
|
|
||||||
body.cp-app-drive { @import "../../../drive/app-drive.less"; }
|
|
||||||
body.cp-app-pad { @import "../../../pad/app-pad.less"; }
|
|
||||||
body.cp-app-code { @import "../../../code/app-code.less"; }
|
|
||||||
body.cp-app-slide { @import "../../../slide/app-slide.less"; }
|
|
||||||
body.cp-app-file { @import "../../../file/app-file.less"; }
|
|
||||||
body.cp-app-filepicker { @import "../../../filepicker/app-filepicker.less"; }
|
|
||||||
body.cp-app-contacts { @import "../../../contacts/app-contacts.less"; }
|
|
||||||
body.cp-app-poll { @import "../../../poll/app-poll.less"; }
|
|
||||||
body.cp-app-whiteboard { @import "../../../whiteboard/app-whiteboard.less"; }
|
|
||||||
body.cp-app-todo { @import "../../../todo/app-todo.less"; }
|
|
||||||
body.cp-app-profile { @import "../../../profile/app-profile.less"; }
|
|
||||||
body.cp-app-settings { @import "../../../settings/app-settings.less"; }
|
|
||||||
body.cp-app-debug { @import "../../../debug/app-debug.less"; }
|
|
||||||
|
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) "./browser.less";
|
@import (reference) "./browser.less";
|
||||||
@import (once) "./variables.less";
|
@import (reference) "./variables.less";
|
||||||
|
|
||||||
.alertify_main () {
|
.alertify_main() {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
};
|
||||||
|
& {
|
||||||
@max-z-index: 2147483647;
|
@max-z-index: 2147483647;
|
||||||
@alertify-fore: @colortheme_modal-fg;
|
@alertify-fore: @colortheme_modal-fg;
|
||||||
@alertify-base: @colortheme_modal-bg;
|
@alertify-base: @colortheme_modal-bg;
|
||||||
@@ -407,3 +410,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
// html
|
.app-noscroll_main() {
|
||||||
.app-noscroll_main () {
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
height: 100%;
|
}
|
||||||
width: 100%;
|
& {
|
||||||
padding: 0px;
|
.cp-app-noscroll {
|
||||||
margin: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
border: 0;
|
|
||||||
body {
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
@@ -17,6 +11,16 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,52 @@
|
|||||||
.app-print_main () {
|
.app-print_main() {
|
||||||
// Current scope is <html>
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
@media print {
|
}
|
||||||
height: auto;
|
& {
|
||||||
max-height: none;
|
.cp-app-print {
|
||||||
overflow: visible;
|
// Current scope is <html>
|
||||||
display: block;
|
@media print {
|
||||||
@page {
|
height: auto;
|
||||||
margin: 0;
|
max-height: none;
|
||||||
size: landscape;
|
overflow: visible;
|
||||||
}
|
|
||||||
// Slide app
|
|
||||||
body.cp-app-slide {
|
|
||||||
display: block;
|
display: block;
|
||||||
.CodeMirror, #cme_toolbox {
|
@page {
|
||||||
display: none;
|
margin: 0;
|
||||||
|
size: landscape;
|
||||||
}
|
}
|
||||||
* {
|
// Slide app
|
||||||
visibility: hidden;
|
body.cp-app-slide {
|
||||||
height: auto;
|
|
||||||
max-height: none;
|
|
||||||
}
|
|
||||||
.cp-app-slide-viewer #cp-app-slide-print {
|
|
||||||
display: block;
|
display: block;
|
||||||
visibility: visible;
|
.CodeMirror, #cme_toolbox {
|
||||||
* {
|
display: none;
|
||||||
visibility: visible;
|
}
|
||||||
|
* {
|
||||||
|
visibility: hidden;
|
||||||
|
height: auto;
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
.cp-app-slide-viewer #cp-app-slide-print {
|
||||||
|
display: block;
|
||||||
|
visibility: visible;
|
||||||
|
* {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-app-slide-viewer #cp-app-slide-modal {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.cp-app-slide-viewer {
|
||||||
|
flex: 1 !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
.cp-toolbar-userlist-drawer {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
#cp-app-slide-editor {
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.cp-app-slide-viewer #cp-app-slide-modal {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.cp-app-slide-viewer {
|
|
||||||
flex: 1 !important;
|
|
||||||
overflow: visible !important;
|
|
||||||
}
|
|
||||||
.cp-toolbar-userlist-drawer {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
#cp-app-slide-editor {
|
|
||||||
height: auto;
|
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,65 @@
|
|||||||
@import (once) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
|
.avatar_vars(
|
||||||
.avatar_main (@width) {
|
@width: 30px
|
||||||
|
) {
|
||||||
|
@avatar-width: @width;
|
||||||
|
@avatar-font-size: @width / 1.2;
|
||||||
|
}
|
||||||
|
.avatar_main(@width: 30px) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
.avatar_vars(@width);
|
||||||
|
--avatar-width: @avatar-width;
|
||||||
|
--avatar-font-size: @avatar-font-size;
|
||||||
|
}
|
||||||
|
& {
|
||||||
|
.avatar_vars();
|
||||||
&.cp-avatar {
|
&.cp-avatar {
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
font-size: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.cp-avatar-default, media-tag {
|
|
||||||
display: inline-flex;
|
|
||||||
width: @width;
|
|
||||||
height: @width;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: content-box;
|
text-overflow: ellipsis;
|
||||||
}
|
font-size: 16px;
|
||||||
.cp-avatar-default {
|
display: flex;
|
||||||
.tools_unselectable();
|
align-items: center;
|
||||||
background: white;
|
.cp-avatar-default, media-tag {
|
||||||
color: black;
|
display: inline-flex;
|
||||||
font-size: @width/1.2;
|
|
||||||
}
|
width: @avatar-width;
|
||||||
media-tag {
|
width: var(--avatar-width);
|
||||||
min-height: @width;
|
|
||||||
min-width: @width;
|
height: @avatar-width;
|
||||||
max-height: @width;
|
height: var(--avatar-width);
|
||||||
max-width: @width;
|
|
||||||
img {
|
justify-content: center;
|
||||||
min-width: 100%;
|
align-items: center;
|
||||||
min-height: 100%;
|
border-radius: 4px;
|
||||||
max-width: none;
|
overflow: hidden;
|
||||||
max-height: none; // To override 'media-tag img' in slide.less
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
.cp-avatar-default {
|
||||||
|
.tools_unselectable();
|
||||||
|
background: white;
|
||||||
|
color: black;
|
||||||
|
font-size: @avatar-font-size;
|
||||||
|
font-size: var(--avatar-font-size);
|
||||||
|
}
|
||||||
|
media-tag {
|
||||||
|
min-height: @avatar-width;
|
||||||
|
min-height: var(--avatar-width);
|
||||||
|
|
||||||
|
min-width: @avatar-width;
|
||||||
|
min-width: var(--avatar-width);
|
||||||
|
|
||||||
|
max-height: @avatar-width;
|
||||||
|
max-height: var(--avatar-width);
|
||||||
|
|
||||||
|
max-width: @avatar-width;
|
||||||
|
max-width: var(--avatar-width);
|
||||||
|
img {
|
||||||
|
min-width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
max-width: none;
|
||||||
|
max-height: none; // To override 'media-tag img' in slide.less
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,28 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
|
||||||
.checkmark_main(@size) {
|
.checkmark_vars(
|
||||||
|
@size: 20px
|
||||||
|
) {
|
||||||
|
@checkmark-size: @size;
|
||||||
|
@checkmark-width: round(@size / 8);
|
||||||
|
@checkmark-dim1: round(@size / 3);
|
||||||
|
@checkmark-dim2: round(2 * @size / 3);
|
||||||
|
@checkmark-top: round(@size / 12) - 1;
|
||||||
|
@checkmark-radio-size: @checkmark-dim1 * 3;
|
||||||
|
}
|
||||||
|
|
||||||
@width: round(@size / 8);
|
.checkmark_main(@size: 20px) {
|
||||||
@dim1: round(@size / 3);
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
@dim2: round(2 * @size / 3);
|
.checkmark_vars(@size);
|
||||||
@top: round(@size / 12) - 1;
|
--checkmark-size: @checkmark-size;
|
||||||
|
--checkmark-width: @checkmark-width;
|
||||||
|
--checkmark-dim1: @checkmark-dim1;
|
||||||
|
--checkmark-dim2: @checkmark-dim2;
|
||||||
|
--checkmark-top: @checkmark-top;
|
||||||
|
--checkmark-radio-size: @checkmark-radio-size;
|
||||||
|
}
|
||||||
|
& {
|
||||||
|
.checkmark_vars();
|
||||||
// <label.cp-checkmark><input><span.cp-checkmark-mark></span>Text</label>
|
// <label.cp-checkmark><input><span.cp-checkmark-mark></span>Text</label>
|
||||||
.cp-checkmark {
|
.cp-checkmark {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -58,8 +75,10 @@
|
|||||||
.cp-checkmark-mark {
|
.cp-checkmark-mark {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: @size;
|
height: @checkmark-size;
|
||||||
width: @size;
|
height: var(--checkmark-size);
|
||||||
|
width: @checkmark-size;
|
||||||
|
width: var(--checkmark-size);
|
||||||
background-color: @colortheme_checkmark-back0;
|
background-color: @colortheme_checkmark-back0;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -68,12 +87,16 @@
|
|||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
display: none;
|
display: none;
|
||||||
margin-top: @top;
|
margin-top: @checkmark-top;
|
||||||
width: @dim1;
|
margin-top: var(--checkmark-top);
|
||||||
height: @dim2;
|
width: @checkmark-dim1;
|
||||||
|
width: var(--checkmark-dim1);
|
||||||
|
height: @checkmark-dim2;
|
||||||
|
height: var(--checkmark-dim2);
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
border: solid @colortheme_checkmark-col1;
|
border: solid @colortheme_checkmark-col1;
|
||||||
border-width: 0 @width @width 0;
|
border-width: 0 @checkmark-width @checkmark-width 0;
|
||||||
|
border-width: 0 var(--checkmark-width) var(--checkmark-width) 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
@@ -129,12 +152,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@radio-size: @dim1 * 3;
|
|
||||||
.cp-radio-mark {
|
.cp-radio-mark {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: @radio-size;
|
height: @checkmark-radio-size;
|
||||||
width: @radio-size;
|
height: var(--checkmark-radio-size);
|
||||||
|
width: @checkmark-radio-size;
|
||||||
|
width: var(--checkmark-radio-size);
|
||||||
background-color: @colortheme_checkmark-back0;
|
background-color: @colortheme_checkmark-back0;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -147,12 +171,14 @@
|
|||||||
content: "";
|
content: "";
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: white;
|
background: white;
|
||||||
width: @dim1;
|
width: @checkmark-dim1;
|
||||||
height: @dim1;
|
width: var(--checkmark-dim1);
|
||||||
|
height: @checkmark-dim1;
|
||||||
|
height: var(--checkmark-dim1);
|
||||||
|
|
||||||
//transform: rotate(45deg);
|
//transform: rotate(45deg);
|
||||||
//border: solid @colortheme_checkmark-col1;
|
//border: solid @colortheme_checkmark-col1;
|
||||||
//border-width: 0 @width @width 0;
|
//border-width: 0 var(--checkmark-width) var(--checkmark-width) 0;
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
//border-color: #FF007C !important;
|
//border-color: #FF007C !important;
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
// create a file: customize/src/less2/include/colortheme.less
|
// create a file: customize/src/less2/include/colortheme.less
|
||||||
// override whatever colors you want. When you update, the new colors will be
|
// override whatever colors you want. When you update, the new colors will be
|
||||||
// added ok because the original file is pulled in first.
|
// added ok because the original file is pulled in first.
|
||||||
@import (once) "/customize.dist/src/less2/include/colortheme.less";
|
@import (reference) "/customize.dist/src/less2/include/colortheme.less";
|
||||||
@import (once) "/customize/src/less2/include/colortheme.less";
|
@import (reference) "/customize/src/less2/include/colortheme.less";
|
||||||
|
|||||||
@@ -99,8 +99,8 @@
|
|||||||
@colortheme_friends-color: #fff;
|
@colortheme_friends-color: #fff;
|
||||||
@colortheme_friends-warn: #cd2532;
|
@colortheme_friends-warn: #cd2532;
|
||||||
|
|
||||||
@colortheme_default-bg: #ddd;
|
@colortheme_default-bg: #326599;
|
||||||
@colortheme_default-color: #000;
|
@colortheme_default-color: #FFF;
|
||||||
@colortheme_default-warn: #cd2532;
|
@colortheme_default-warn: #cd2532;
|
||||||
|
|
||||||
@colortheme_settings-bg: #0087ff;
|
@colortheme_settings-bg: #0087ff;
|
||||||
|
|||||||
@@ -1,12 +1,27 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./browser.less";
|
||||||
@import (once) "./tools.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) './icon-colors.less';
|
@import (reference) "./tools.less";
|
||||||
|
@import (reference) './icon-colors.less';
|
||||||
|
|
||||||
|
.creation_vars(
|
||||||
|
@color: @colortheme_default-color,
|
||||||
|
@bg-color: @colortheme_default-bg
|
||||||
|
) {
|
||||||
|
@creation-color: @color;
|
||||||
|
@creation-bg-color: @bg-color;
|
||||||
|
};
|
||||||
|
|
||||||
.creation_main(
|
.creation_main(
|
||||||
@color: @colortheme_default-color, // Color of the text for the toolbar
|
@color: @colortheme_default-color,
|
||||||
@bg-color: @colortheme_default-bg, // color of the toolbar background
|
@bg-color: @colortheme_default-bg
|
||||||
@warn-color: @colortheme_default-warn, // color of the warning text in the toolbar
|
|
||||||
) {
|
) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
.creation_vars(@color, @bg-color);
|
||||||
|
--creation-color: @color;
|
||||||
|
--creation-bg-color: @bg-color;
|
||||||
|
}
|
||||||
|
& {
|
||||||
|
.creation_vars();
|
||||||
@colortheme_creation-modal-bg: #fff;
|
@colortheme_creation-modal-bg: #fff;
|
||||||
@colortheme_creation-modal: #666;
|
@colortheme_creation-modal: #666;
|
||||||
@colortheme_creation-modal-title: @colortheme_loading-bg;
|
@colortheme_creation-modal-title: @colortheme_loading-bg;
|
||||||
@@ -116,6 +131,8 @@
|
|||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
label {
|
label {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
// Force wrap when the other element in the line is 100% (IE bug):
|
||||||
|
min-width: 1px;
|
||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
&+ label {
|
&+ label {
|
||||||
@@ -141,15 +158,19 @@
|
|||||||
//margin-top: 10px;
|
//margin-top: 10px;
|
||||||
&.active {
|
&.active {
|
||||||
transition: max-height 0.5s ease-in-out;
|
transition: max-height 0.5s ease-in-out;
|
||||||
max-width: unset;
|
max-width: none;
|
||||||
max-height: 100px;
|
max-height: 100px;
|
||||||
}
|
}
|
||||||
|
input, select {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input, select {
|
input, select {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border: 1px solid @colortheme_form-border;
|
border: 1px solid @colortheme_form-border;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
background-color: @colortheme_form-bg;
|
background-color: @colortheme_form-bg;
|
||||||
color: @colortheme_form-color;
|
color: @colortheme_form-color;
|
||||||
}
|
}
|
||||||
@@ -167,7 +188,7 @@
|
|||||||
}
|
}
|
||||||
&.active {
|
&.active {
|
||||||
label {
|
label {
|
||||||
flex: unset;
|
flex: none;
|
||||||
}
|
}
|
||||||
.cp-creation-slider {
|
.cp-creation-slider {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -184,7 +205,7 @@
|
|||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
label {
|
label {
|
||||||
flex: unset;
|
flex: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -258,22 +279,19 @@
|
|||||||
color: black;
|
color: black;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
|
||||||
&.cp-creation-template-selected {
|
&.cp-creation-template-selected, &:hover {
|
||||||
color: @color !important;
|
color: @creation-color !important;
|
||||||
background-color: @bg-color !important;
|
color: var(--creation-color) !important;
|
||||||
.fa {
|
background-color: @creation-bg-color !important;
|
||||||
color: @color;
|
background-color: var(--creation-bg-color) !important;
|
||||||
|
.fa, .cptools {
|
||||||
|
color: @creation-color;
|
||||||
|
color: var(--creation-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transition: all 0.1s;
|
transition: all 0.1s;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
//color: @colortheme_modal-fg;
|
|
||||||
background-color: @colortheme_form-border;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@@ -287,13 +305,15 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
min-height: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
.fa {
|
.fa, .cptools {
|
||||||
color: @bg-color;
|
color: @creation-bg-color;
|
||||||
|
color: var(--creation-bg-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
@@ -340,7 +360,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
.cp-creation-slider {
|
.cp-creation-slider {
|
||||||
flex: unset;
|
flex: none;
|
||||||
order: 10;
|
order: 10;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
|
|
||||||
/* The container <div> - needed to position the dropdown content */
|
/* The container <div> - needed to position the dropdown content */
|
||||||
.dropdown_main () {
|
.dropdown_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.cp-dropdown-container {
|
.cp-dropdown-container {
|
||||||
@dropdown_font: @colortheme_app-font-size @colortheme_font;
|
@dropdown_font: @colortheme_app-font-size @colortheme_font;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
@import (once) './colortheme-all.less';
|
@import (reference) './colortheme-all.less';
|
||||||
@import (once) './modal.less';
|
@import (reference) './modal.less';
|
||||||
|
|
||||||
.fileupload_main () {
|
.fileupload_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
.modal_main();
|
||||||
|
}
|
||||||
|
& {
|
||||||
/* Upload status table */
|
/* Upload status table */
|
||||||
#cp-fileupload {
|
#cp-fileupload {
|
||||||
.modal_base();
|
.modal_base();
|
||||||
@@ -54,4 +58,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
.font_neuropolitical () {
|
.font_main () {
|
||||||
@font-face {
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
font-family: Neuropolitical;
|
|
||||||
src: url("/customize/fonts/neuropolitical.ttf");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.font_open-sans () {
|
|
||||||
@import (once) '/customize/fonts/open-sans.less';
|
// Fonts need to go on the global scope
|
||||||
|
@font-face {
|
||||||
|
font-family: Neuropolitical;
|
||||||
|
src: url("/customize/fonts/neuropolitical.ttf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fonts need to go on the global scope
|
||||||
|
@font-tools {
|
||||||
|
font-family: CryptPadTools;
|
||||||
|
src: url("/customize/fonts/cryptpadtools.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@import (once) '/customize/fonts/open-sans.less';
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +1,58 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) "./toolbar.less";
|
@import (reference) "./toolbar.less";
|
||||||
@import (once) './fileupload.less';
|
@import (reference) './fileupload.less';
|
||||||
@import (once) './alertify.less';
|
@import (reference) './alertify.less';
|
||||||
@import (once) './tokenfield.less';
|
@import (reference) './tokenfield.less';
|
||||||
@import (once) './creation.less';
|
@import (reference) './creation.less';
|
||||||
@import (once) './tippy.less';
|
@import (reference) './tippy.less';
|
||||||
@import (once) "./checkmark.less";
|
@import (reference) "./checkmark.less";
|
||||||
@import (once) "./password-input.less";
|
@import (reference) "./password-input.less";
|
||||||
|
@import (reference) './font.less';
|
||||||
|
@import (reference) "./app-print.less";
|
||||||
|
@import (reference) "./app-noscroll.less";
|
||||||
|
|
||||||
.framework_main(@bg-color, @warn-color, @color) {
|
.framework_main(@bg-color, @warn-color, @color) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
// Set the HTML style for the apps which shouldn't have a body scrollbar
|
||||||
|
.app-noscroll_main();
|
||||||
|
|
||||||
|
// Set the HTML style for printing slides
|
||||||
|
.app-print_main();
|
||||||
|
|
||||||
|
.font_main();
|
||||||
|
|
||||||
.toolbar_main(
|
.toolbar_main(
|
||||||
@bg-color: @bg-color,
|
@bg-color: @bg-color,
|
||||||
@warn-color: @warn-color,
|
@warn-color: @warn-color,
|
||||||
@color: @color
|
@color: @color
|
||||||
);
|
);
|
||||||
.fileupload_main();
|
|
||||||
.alertify_main();
|
.alertify_main();
|
||||||
|
.fileupload_main();
|
||||||
.tokenfield_main();
|
.tokenfield_main();
|
||||||
.tippy_main();
|
.tippy_main();
|
||||||
.checkmark_main(20px);
|
.checkmark_main(20px);
|
||||||
.password_main();
|
.password_main();
|
||||||
.creation_main(
|
.creation_main(
|
||||||
@bg-color: @bg-color,
|
@bg-color: @bg-color,
|
||||||
@warn-color: @warn-color,
|
|
||||||
@color: @color
|
@color: @color
|
||||||
);
|
);
|
||||||
font: @colortheme_app-font;
|
font: @colortheme_app-font;
|
||||||
}
|
};
|
||||||
|
|
||||||
.framework_min_main(
|
.framework_min_main(
|
||||||
@color: @colortheme_default-color, // Color of the text for the toolbar
|
@color: @colortheme_default-color, // Color of the text for the toolbar
|
||||||
@bg-color: @colortheme_default-bg, // color of the toolbar background
|
@bg-color: @colortheme_default-bg, // color of the toolbar background
|
||||||
@warn-color: @colortheme_default-warn, // color of the warning text in the toolbar
|
@warn-color: @colortheme_default-warn, // color of the warning text in the toolbar
|
||||||
) {
|
) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
// Set the HTML style for the apps which shouldn't have a body scrollbar
|
||||||
|
.app-noscroll_main();
|
||||||
|
|
||||||
|
// Set the HTML style for printing slides
|
||||||
|
.app-print_main();
|
||||||
|
|
||||||
|
.font_main();
|
||||||
|
|
||||||
.toolbar_main(
|
.toolbar_main(
|
||||||
@bg-color: @bg-color,
|
@bg-color: @bg-color,
|
||||||
@warn-color: @warn-color,
|
@warn-color: @warn-color,
|
||||||
@@ -46,4 +66,7 @@
|
|||||||
font: @colortheme_app-font;
|
font: @colortheme_app-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& {
|
||||||
|
body.cp-readonly .cp-hidden-if-readonly { display: none !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,30 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
|
||||||
.help_main (@color, @bg-color) {
|
.help_vars (
|
||||||
|
@color: @colortheme_default-color,
|
||||||
|
@bg-color: @colortheme_default-bg
|
||||||
|
) {
|
||||||
|
@help-bg-color-l15: lighten(@bg-color, 15%);
|
||||||
|
@help-text-color: contrast(@help-bg-color-l15, #fff, #000); //@color;
|
||||||
|
@help-link-color: contrast(@help-bg-color-l15, lighten(spin(@bg-color, 180), 10%), darken(spin(@bg-color, 180), 10%));
|
||||||
|
}
|
||||||
|
.help_main (
|
||||||
|
@color: @colortheme_default-color,
|
||||||
|
@bg-color: @colortheme_default-bg
|
||||||
|
) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
.help_vars(@color, @bg-color);
|
||||||
|
--help-bg-color-l15: @help-bg-color-l15;
|
||||||
|
--help-text-color: @help-text-color;
|
||||||
|
--help-link-color: @help-link-color;
|
||||||
|
};
|
||||||
|
& {
|
||||||
|
.help_vars();
|
||||||
.cp-help-container {
|
.cp-help-container {
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: lighten(@bg-color, 15%);
|
background-color: @help-bg-color-l15;
|
||||||
|
background-color: var(--help-bg-color-l15);
|
||||||
&.cp-help-hidden {
|
&.cp-help-hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -14,14 +35,13 @@
|
|||||||
right: 5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
.cp-help-text {
|
.cp-help-text {
|
||||||
color: contrast(lighten(@bg-color, 15%), #fff, #000); //@color;
|
color: @help-text-color;
|
||||||
|
color: var(--help-text-color);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
a {
|
a {
|
||||||
//color: darken(@colortheme_link-color, 30%);
|
color: @help-link-color;
|
||||||
@spin: spin(lighten(@bg-color, 15%), 180);
|
color: var(--help-link-color);
|
||||||
color: contrast(lighten(@bg-color, 15%), lighten(@spin, 10%), darken(@spin, 10%));
|
|
||||||
//color: darken(spin(lighten(@bg-color, 15%), 180), 10%);
|
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
@@ -36,3 +56,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
.iconColors_main () {
|
.iconColors_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
// Classes used in common-interface.js
|
// Classes used in common-interface.js
|
||||||
.cp-icon-color-pad { color: @colortheme_pad-bg; }
|
.cp-icon-color-pad { color: @colortheme_pad-bg; }
|
||||||
.cp-icon-color-code { color: @colortheme_code-bg; }
|
.cp-icon-color-code { color: @colortheme_code-bg; }
|
||||||
|
|||||||
@@ -1,10 +1,25 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
@import (reference) "./font.less";
|
||||||
|
|
||||||
@infopages_infobar-height: 64px;
|
.infopages_link () {
|
||||||
@infopages_padding: 32px;
|
text-decoration: none;
|
||||||
|
color: #0275D8;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Basic setup for info pages, this should be used at the global level
|
|
||||||
.infopages_main () {
|
.infopages_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
.font_main();
|
||||||
|
@infopages_infobar-height: 64px;
|
||||||
|
@infopages_padding: 32px;
|
||||||
|
|
||||||
|
// Basic setup for info pages, this should be used at the global level
|
||||||
background-color: @colortheme_info-background;
|
background-color: @colortheme_info-background;
|
||||||
a {
|
a {
|
||||||
color: @cryptpad_color_blue;
|
color: @cryptpad_color_blue;
|
||||||
@@ -100,20 +115,8 @@
|
|||||||
border-top: 2px solid #fff;
|
border-top: 2px solid #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
.infopages_link () {
|
// Apply this to the top bar div
|
||||||
text-decoration: none;
|
|
||||||
color: #0275D8;
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-flex;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply this to the top bar div
|
|
||||||
.infopages_topbar () {
|
|
||||||
.cp-topbar {
|
.cp-topbar {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
z-index: 10000; //Z infopage toolbar
|
z-index: 10000; //Z infopage toolbar
|
||||||
@@ -149,71 +152,72 @@
|
|||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// navigation top bar
|
// navigation top bar
|
||||||
.navbar {
|
.navbar {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
.navbar-brand {
|
.navbar-brand {
|
||||||
display: block;
|
display: block;
|
||||||
background-image: url(/customize/CryptPad_logo_color.svg);
|
background-image: url(/customize/CryptPad_logo_color.svg);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
@media (max-width: 326px) {
|
@media (max-width: 326px) {
|
||||||
width: 180px;
|
width: 180px;
|
||||||
|
}
|
||||||
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
margin-right: 0;
|
a {
|
||||||
}
|
border: 2px solid transparent;
|
||||||
a {
|
white-space: nowrap;
|
||||||
border: 2px solid transparent;
|
}
|
||||||
white-space: nowrap;
|
.nav-link {
|
||||||
}
|
padding: 0.5em 0.7em;
|
||||||
.nav-link {
|
&:hover {
|
||||||
padding: 0.5em 0.7em;
|
color: @cryptpad_color_light_blue;
|
||||||
&:hover {
|
}
|
||||||
color: @cryptpad_color_light_blue;
|
}
|
||||||
|
.cp-register-btn {
|
||||||
|
border: 2px solid #4591C4;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
button:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.navbar-toggler {
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #4591C4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-register-btn {
|
@media (max-width: 1000px) {
|
||||||
border: 2px solid #4591C4;
|
#menuCollapse {
|
||||||
display: inline-block;
|
text-align: right;
|
||||||
}
|
/* @media (min-width: 576px) {
|
||||||
button:focus {
|
top: 100%;
|
||||||
outline: none;
|
background: rgba(255,255,255,0.8);
|
||||||
}
|
position: absolute;
|
||||||
.navbar-toggler {
|
right: 0px;
|
||||||
margin-top: 10px;
|
padding: 0 20px;
|
||||||
color: #4591C4;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
}
|
*/
|
||||||
@media (max-width: 1000px) {
|
}
|
||||||
#menuCollapse {
|
.navbar-nav a {
|
||||||
text-align: right;
|
text-align: right !important;
|
||||||
/* @media (min-width: 576px) {
|
}
|
||||||
top: 100%;
|
.cp-register-btn {
|
||||||
background: rgba(255,255,255,0.8);
|
margin-right: 13px;
|
||||||
position: absolute;
|
text-align: center;
|
||||||
right: 0px;
|
|
||||||
padding: 0 20px;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
.navbar-nav a {
|
|
||||||
text-align: right !important;
|
//footer general styles
|
||||||
}
|
|
||||||
.cp-register-btn {
|
.footer-title {
|
||||||
margin-right: 13px;
|
font-weight: bold;
|
||||||
text-align: center;
|
font-size: 1.2em;
|
||||||
|
color: #1E1F1F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//footer general styles
|
|
||||||
|
|
||||||
.footer-title {
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.2em;
|
|
||||||
color: #1E1F1F;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@import (once) "./unselectable.less";
|
@import (reference) "./unselectable.less";
|
||||||
@import (once) "./variables.less";
|
@import (reference) "./variables.less";
|
||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
|
||||||
.leftside-menu_main() {
|
.leftside-menu_main() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
|
||||||
.limit-bar_main () {
|
.limit-bar_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.cp-limit-container {
|
.cp-limit-container {
|
||||||
@colortheme_green: #5cb85c;
|
@colortheme_green: #5cb85c;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
|
||||||
|
|
||||||
.markdownToolbar_main (@color, @bg-color) {
|
|
||||||
.cp-markdown-toolbar {
|
|
||||||
height: @toolbar_line-height;
|
|
||||||
background-color: lighten(@bg-color, 20%);
|
|
||||||
display: none;
|
|
||||||
button {
|
|
||||||
height: @toolbar_line-height !important;
|
|
||||||
outline: 0;
|
|
||||||
color: @color;
|
|
||||||
.toolbar_button;
|
|
||||||
font: normal normal normal 14px/1 FontAwesome;
|
|
||||||
&:hover {
|
|
||||||
background-color: lighten(@bg-color, 8%);
|
|
||||||
}
|
|
||||||
&.cp-markdown-help { float: right; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
.markdown_main() {
|
||||||
|
blockquote {
|
||||||
|
background: #e5e5e5;
|
||||||
|
padding: 10px;
|
||||||
|
border-left: 3px solid #999;
|
||||||
|
padding-right: 0;
|
||||||
|
p { margin: 0; }
|
||||||
|
blockquote { margin: 0; }
|
||||||
|
}
|
||||||
|
// todo ul, ol
|
||||||
|
}
|
||||||
|
|
||||||
.markdown_preformatted-code (@color: #333) {
|
.markdown_preformatted-code (@color: #333) {
|
||||||
pre > code {
|
pre > code {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -23,15 +35,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown_main() {
|
|
||||||
blockquote {
|
|
||||||
background: #e5e5e5;
|
|
||||||
padding: 10px;
|
|
||||||
border-left: 3px solid #999;
|
|
||||||
padding-right: 0;
|
|
||||||
p { margin: 0; }
|
|
||||||
blockquote { margin: 0; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// todo ul, ol
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) "./variables.less";
|
@import (reference) "./variables.less";
|
||||||
|
|
||||||
.modal_base() {
|
.modal_base() {
|
||||||
font-family: @colortheme_font;
|
font-family: @colortheme_font;
|
||||||
@@ -17,62 +17,68 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cp-modal-container {
|
.modal_main() {
|
||||||
display: none;
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
z-index: 100000; //Z modal container
|
& {
|
||||||
position: absolute;
|
.cp-modal-container {
|
||||||
top: 0;
|
display: none;
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
background-color: @colortheme_modal-dim;
|
|
||||||
|
|
||||||
.cp-modal {
|
|
||||||
background-color: @colortheme_modal-bg;
|
|
||||||
color: @colortheme_modal-fg;
|
|
||||||
box-shadow: @variables_shadow;
|
|
||||||
|
|
||||||
padding: @variables_padding;
|
|
||||||
|
|
||||||
|
z-index: 100000; //Z modal container
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 15vh; bottom: 15vh;
|
top: 0;
|
||||||
left: 10vw; right: 10vw;
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: @colortheme_modal-dim;
|
||||||
|
|
||||||
overflow: auto;
|
.cp-modal {
|
||||||
|
background-color: @colortheme_modal-bg;
|
||||||
|
color: @colortheme_modal-fg;
|
||||||
|
box-shadow: @variables_shadow;
|
||||||
|
|
||||||
font-family: @colortheme_font;
|
padding: @variables_padding;
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-modal-form {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
background-color: @colortheme_modal-input;
|
|
||||||
color: @colortheme_modal-input-fg;
|
|
||||||
border: 0;
|
|
||||||
padding: 8px 12px;
|
|
||||||
margin: 1em;
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-modal-close {
|
|
||||||
text-shadow: none;
|
|
||||||
color: inherit;
|
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 15vh; bottom: 15vh;
|
||||||
right: 0;
|
left: 10vw; right: 10vw;
|
||||||
margin: @variables_padding;
|
|
||||||
cursor: pointer;
|
overflow: auto;
|
||||||
|
|
||||||
|
font-family: @colortheme_font;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
& > p {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-modal-form {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
background-color: @colortheme_modal-input;
|
||||||
|
color: @colortheme_modal-input-fg;
|
||||||
|
border: 0;
|
||||||
|
padding: 8px 12px;
|
||||||
|
margin: 1em;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-modal-close {
|
||||||
|
text-shadow: none;
|
||||||
|
color: inherit;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: @variables_padding;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
.password_main() {
|
.password_main() {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.cp-password-container {
|
.cp-password-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
@import (once) "/customize/src/less2/include/colortheme-all.less";
|
@import (reference) "/customize/src/less2/include/colortheme-all.less";
|
||||||
@import (once) "/customize/src/less2/include/leftside-menu.less";
|
@import (reference) "/customize/src/less2/include/leftside-menu.less";
|
||||||
|
|
||||||
@leftside-bg: @colortheme_sidebar-left-bg;
|
|
||||||
@leftside-color: @colortheme_sidebar-left-fg;
|
|
||||||
@rightside-color: @colortheme_sidebar-right-fg;
|
|
||||||
@description-color: @colortheme_sidebar-description;
|
|
||||||
|
|
||||||
@sidebar_button-width: 400px;
|
@sidebar_button-width: 400px;
|
||||||
|
|
||||||
|
|
||||||
.sidebar-layout_main() {
|
.sidebar-layout_main() {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
|
||||||
|
// This is way too broad to put in the global scope
|
||||||
input[type="text"], input[type="password"] {
|
input[type="text"], input[type="password"] {
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
& {
|
||||||
|
@leftside-bg: @colortheme_sidebar-left-bg;
|
||||||
|
@leftside-color: @colortheme_sidebar-left-fg;
|
||||||
|
@rightside-color: @colortheme_sidebar-right-fg;
|
||||||
|
@description-color: @colortheme_sidebar-description;
|
||||||
|
|
||||||
#cp-sidebarlayout-container {
|
#cp-sidebarlayout-container {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
@import (once) './colortheme-all.less';
|
@import (reference) './colortheme-all.less';
|
||||||
|
|
||||||
.tippy_main() {
|
.tippy_main() {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.tippy-tooltip.cryptpad-theme {
|
.tippy-tooltip.cryptpad-theme {
|
||||||
/* Your styling here. Example: */
|
/* Your styling here. Example: */
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
@import (once) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
|
|
||||||
.tokenfield_main () {
|
.tokenfield_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.ui-autocomplete {
|
.ui-autocomplete {
|
||||||
z-index: 100001; // alertify + 1
|
z-index: 100001; // alertify + 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
|
|
||||||
.history_main () {
|
.history_main () {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
}
|
||||||
|
& {
|
||||||
.cp-toolbar-history {
|
.cp-toolbar-history {
|
||||||
display: none;
|
display: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|||||||
@@ -1,15 +1,36 @@
|
|||||||
@import (once) "./dropdown.less";
|
@import (reference) "./dropdown.less";
|
||||||
@import (once) "./colortheme-all.less";
|
@import (reference) "./colortheme-all.less";
|
||||||
@import (once) "./browser.less";
|
@import (reference) "./browser.less";
|
||||||
@import (once) "./ckeditor-fix.less";
|
@import (reference) "./ckeditor-fix.less";
|
||||||
@import (once) "./avatar.less";
|
@import (reference) "./avatar.less";
|
||||||
@import (once) "./toolbar-history.less";
|
@import (reference) "./toolbar-history.less";
|
||||||
@import (once) "./icon-colors.less";
|
@import (reference) "./icon-colors.less";
|
||||||
@import (once) "./tools.less";
|
@import (reference) "./tools.less";
|
||||||
@import (once) "./icons.less";
|
@import (reference) "./icons.less";
|
||||||
@import (once) "./modal.less";
|
@import (reference) "./modal.less";
|
||||||
@import (once) "./markdown-toolbar.less";
|
@import (reference) "./help.less";
|
||||||
@import (once) "./help.less";
|
|
||||||
|
.toolbar_vars (
|
||||||
|
@color: @colortheme_default-color, // Color of the text for the toolbar
|
||||||
|
@bg-color: @colortheme_default-bg, // color of the toolbar background
|
||||||
|
@warn-color: @colortheme_default-warn // color of the warning text in the toolbar
|
||||||
|
) {
|
||||||
|
@toolbar-color: @color;
|
||||||
|
@toolbar-color-l20: lighten(@color, 20%);
|
||||||
|
@toolbar-color-d20: darken(@color, 20%);
|
||||||
|
@toolbar-color-d15: darken(@color, 15%);
|
||||||
|
|
||||||
|
@toolbar-bg-color: @bg-color;
|
||||||
|
@toolbar-bg-color-l8: lighten(@bg-color, 8%);
|
||||||
|
@toolbar-bg-color-l20: lighten(@bg-color, 20%);
|
||||||
|
@toolbar-bg-color-d5: darken(@bg-color, 5%);
|
||||||
|
@toolbar-bg-color-d10: darken(@bg-color, 10%);
|
||||||
|
@toolbar-bg-color-d15: darken(@bg-color, 15%);
|
||||||
|
|
||||||
|
@toolbar-warn-color: @warn-color;
|
||||||
|
|
||||||
|
@toolbar-userlist-name-edit: contrast(@toolbar-color, @toolbar-color-l20, @toolbar-color-d20);
|
||||||
|
};
|
||||||
|
|
||||||
.toolbar_main (
|
.toolbar_main (
|
||||||
@color: @colortheme_default-color, // Color of the text for the toolbar
|
@color: @colortheme_default-color, // Color of the text for the toolbar
|
||||||
@@ -17,7 +38,41 @@
|
|||||||
@warn-color: @colortheme_default-warn, // color of the warning text in the toolbar
|
@warn-color: @colortheme_default-warn, // color of the warning text in the toolbar
|
||||||
@barWidth: 600px // width of the toolbar
|
@barWidth: 600px // width of the toolbar
|
||||||
) {
|
) {
|
||||||
|
--LessLoader_require: LessLoader_currentFile();
|
||||||
|
.toolbar_vars(@color, @bg-color, @warn-color);
|
||||||
|
|
||||||
|
--toolbar-color: @toolbar-color;
|
||||||
|
--toolbar-color-l20: @toolbar-color-l20;
|
||||||
|
--toolbar-color-d20: @toolbar-color-d20;
|
||||||
|
--toolbar-color-d15: @toolbar-color-d15;
|
||||||
|
|
||||||
|
--toolbar-bg-color: @toolbar-bg-color;
|
||||||
|
--toolbar-bg-color-l8: @toolbar-bg-color-l8;
|
||||||
|
--toolbar-bg-color-l20: @toolbar-bg-color-l20;
|
||||||
|
--toolbar-bg-color-d5: @toolbar-bg-color-d5;
|
||||||
|
--toolbar-bg-color-d10: @toolbar-bg-color-d10;
|
||||||
|
--toolbar-bg-color-d15: @toolbar-bg-color-d15;
|
||||||
|
|
||||||
|
--toolbar-warn-color: @toolbar-warn-color;
|
||||||
|
|
||||||
|
--toolbar-userlist-name-edit: @toolbar-userlist-name-edit;
|
||||||
|
|
||||||
|
@media screen and (max-width: @barWidth) {
|
||||||
|
.cp-toolbar-rightside {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.help_main(@color, @bg-color);
|
||||||
|
.dropdown_main();
|
||||||
|
.history_main();
|
||||||
|
.iconColors_main();
|
||||||
|
.modal_main();
|
||||||
|
};
|
||||||
|
& {
|
||||||
|
.toolbar_vars();
|
||||||
@toolbar_line-height: 32px;
|
@toolbar_line-height: 32px;
|
||||||
@toolbar_top-height: 64px;
|
@toolbar_top-height: 64px;
|
||||||
@toolbar_button-font: @colortheme_app-font;
|
@toolbar_button-font: @colortheme_app-font;
|
||||||
@@ -26,12 +81,27 @@
|
|||||||
// this is a workaround
|
// this is a workaround
|
||||||
.fa-shhare-alt:before { content: "\f1e0"; }
|
.fa-shhare-alt:before { content: "\f1e0"; }
|
||||||
|
|
||||||
.dropdown_main();
|
|
||||||
.ckeditor_fix();
|
.ckeditor_fix();
|
||||||
.history_main();
|
|
||||||
.iconColors_main();
|
.cp-markdown-toolbar {
|
||||||
.markdownToolbar_main(@color, @bg-color);
|
height: @toolbar_line-height;
|
||||||
.help_main(@color, @bg-color);
|
background-color: @toolbar-bg-color-l20;
|
||||||
|
background-color: var(--toolbar-bg-color-l20);
|
||||||
|
display: none;
|
||||||
|
button {
|
||||||
|
height: @toolbar_line-height !important;
|
||||||
|
outline: 0;
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
|
.toolbar_button;
|
||||||
|
font: normal normal normal 14px/1 FontAwesome;
|
||||||
|
&:hover {
|
||||||
|
background-color: @toolbar-bg-color-l8;
|
||||||
|
background-color: var(--toolbar-bg-color-l8);
|
||||||
|
}
|
||||||
|
&.cp-markdown-help { float: right; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.cp-toolbar-container {
|
.cp-toolbar-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -65,7 +135,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cp-toolbar-userlist-drawer {
|
.cp-toolbar-userlist-drawer {
|
||||||
background-color: @bg-color;
|
background-color: @toolbar-bg-color;
|
||||||
|
background-color: var(--toolbar-bg-color);
|
||||||
font: @colortheme_app-font-size @colortheme_font;
|
font: @colortheme_app-font-size @colortheme_font;
|
||||||
min-width: 175px;
|
min-width: 175px;
|
||||||
width: 175px;
|
width: 175px;
|
||||||
@@ -253,31 +324,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cp-toolbar-userlist-drawer {
|
.cp-toolbar-userlist-drawer {
|
||||||
background-color: @bg-color;
|
background-color: @toolbar-bg-color;
|
||||||
color: @color;
|
background-color: var(--toolbar-bg-color);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
.cp-toolbar-userlist-drawer-close {
|
.cp-toolbar-userlist-drawer-close {
|
||||||
color: @color;
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
h2 {
|
h2 {
|
||||||
background-color: darken(@bg-color, 10%);
|
background-color: @toolbar-bg-color-d10;
|
||||||
color: @color;
|
background-color: var(--toolbar-bg-color-d10);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
.cp-toolbar-userlist-name-input {
|
.cp-toolbar-userlist-name-input {
|
||||||
background-color: darken(@bg-color, 10%);
|
background-color: @toolbar-bg-color-d10;
|
||||||
color: @color;
|
background-color: var(--toolbar-bg-color-d10);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
.cp-toolbar-userlist-name-edit {
|
.cp-toolbar-userlist-name-edit {
|
||||||
color: contrast(@color,
|
color: @toolbar-userlist-name-edit;
|
||||||
lighten(@color, 20%),
|
color: var(--toolbar-userlist-name-edit);
|
||||||
darken(@color, 20%));
|
|
||||||
background: transparent;
|
background: transparent;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: @color;
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-toolbar-userlist-friend {
|
.cp-toolbar-userlist-friend {
|
||||||
&:hover {
|
&:hover {
|
||||||
color: darken(@color, 15%);
|
color: @toolbar-color-d15;
|
||||||
|
color: var(--toolbar-color-d15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,8 +376,10 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
background-color: @bg-color;
|
background-color: @toolbar-bg-color;
|
||||||
color: @color;
|
background-color: var(--toolbar-bg-color);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
|
|
||||||
.fa {
|
.fa {
|
||||||
font: normal normal normal 14px/1 FontAwesome;
|
font: normal normal normal 14px/1 FontAwesome;
|
||||||
@@ -516,42 +597,57 @@
|
|||||||
|
|
||||||
.cp-toolbar-spinner {
|
.cp-toolbar-spinner {
|
||||||
font-size: @colortheme_app-font-size;
|
font-size: @colortheme_app-font-size;
|
||||||
color: @color;
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
.cp-toolbar-limit {
|
.cp-toolbar-limit {
|
||||||
text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color;
|
text-shadow: -1px 0 @toolbar-color, 0 1px @toolbar-color, 1px 0 @toolbar-color, 0 -1px @toolbar-color;
|
||||||
color: @warn-color;
|
text-shadow: -1px 0 var(--toolbar-color), 0 1px var(--toolbar-color), 1px 0 var(--toolbar-color), 0 -1px var(--toolbar-color);
|
||||||
|
color: @toolbar-warn-color;
|
||||||
|
color: var(--toolbar-warn-color);
|
||||||
}
|
}
|
||||||
.cp-toolbar-leftside, .cp-toolbar-rightside {
|
.cp-toolbar-leftside, .cp-toolbar-rightside {
|
||||||
background-color: lighten(@bg-color, 8%);
|
background-color: @toolbar-bg-color-l8;
|
||||||
|
background-color: var(--toolbar-bg-color-l8);
|
||||||
button:hover, button.cp-toolbar-button-active {
|
button:hover, button.cp-toolbar-button-active {
|
||||||
background-color: @bg-color;
|
background-color: @toolbar-bg-color;
|
||||||
|
background-color: var(--toolbar-bg-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-toolbar-title-hoverable:hover {
|
.cp-toolbar-title-hoverable:hover {
|
||||||
.cp-toolbar-title-editable, .cp-toolbar-title-edit {
|
.cp-toolbar-title-editable, .cp-toolbar-title-edit {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
border: 1px solid darken(@bg-color, 15%);
|
border: 1px solid @toolbar-bg-color-d15;
|
||||||
background: darken(@bg-color, 10%);
|
border: 1px solid var(--toolbar-bg-color-d15);
|
||||||
|
background: @toolbar-bg-color-d10;
|
||||||
|
background: var(--toolbar-bg-color-d10);
|
||||||
transition: all 0.15s;
|
transition: all 0.15s;
|
||||||
color: @color;
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
.cp-toolbar-title-editable {
|
.cp-toolbar-title-editable {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-toolbar-title-save {
|
.cp-toolbar-title-save {
|
||||||
border: 1px solid darken(@bg-color, 15%);
|
border: 1px solid @toolbar-bg-color-d15;
|
||||||
background: darken(@bg-color, 10%);
|
border: 1px solid var(--toolbar-bg-color-d15);
|
||||||
color: @color;
|
background: @toolbar-bg-color-d10;
|
||||||
|
background: var(--toolbar-bg-color-d10);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
&:hover {
|
&:hover {
|
||||||
background: darken(@bg-color, 5%);
|
background: @toolbar-bg-color-d5;
|
||||||
|
background: var(--toolbar-bg-color-d5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
border: 1px solid darken(@bg-color, 15%);
|
border: 1px solid @toolbar-bg-color-d15;
|
||||||
background: darken(@bg-color, 10%);
|
border: 1px solid var(--toolbar-bg-color-d15);
|
||||||
color: @color;
|
background: @toolbar-bg-color-d10;
|
||||||
|
background: var(--toolbar-bg-color-d10);
|
||||||
|
color: @toolbar-color;
|
||||||
|
color: var(--toolbar-color);
|
||||||
}
|
}
|
||||||
.cp-dropdown-content.cp-dropdown-left a {
|
.cp-dropdown-content.cp-dropdown-left a {
|
||||||
color: black;
|
color: black;
|
||||||
@@ -577,7 +673,8 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
font-size: @colortheme_app-font-size;
|
font-size: @colortheme_app-font-size;
|
||||||
color: @warn-color;
|
color: @toolbar-warn-color;
|
||||||
|
color: var(--toolbar-warn-color);
|
||||||
.cp-pnp-msg {
|
.cp-pnp-msg {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
font-family: @colortheme_font;
|
font-family: @colortheme_font;
|
||||||
@@ -586,7 +683,8 @@
|
|||||||
font-size: @colortheme_app-font-size;
|
font-size: @colortheme_app-font-size;
|
||||||
font-family: @colortheme_font;
|
font-family: @colortheme_font;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: @warn-color;
|
color: @toolbar-warn-color;
|
||||||
|
color: var(--toolbar-warn-color);
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
@@ -880,11 +978,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
min-height: @toolbar_line-height;
|
min-height: @toolbar_line-height;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@media screen and (max-width: @barWidth) { // 450px
|
|
||||||
flex-wrap: wrap;
|
|
||||||
height: auto;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
&:empty {
|
&:empty {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
@@ -1003,6 +1096,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
@import (once) './include/font.less';
|
|
||||||
.font_neuropolitical();
|
|
||||||
.font_open-sans();
|
|
||||||
|
|
||||||
body.cp-page-index { @import "./pages/page-index.less"; }
|
|
||||||
body.cp-page-contact { @import "./pages/page-contact.less"; }
|
|
||||||
body.cp-page-login { @import "./pages/page-login.less"; }
|
|
||||||
body.cp-page-register { @import "./pages/page-register.less"; }
|
|
||||||
body.cp-page-what-is-cryptpad { @import "./pages/page-what-is-cryptpad.less"; }
|
|
||||||
body.cp-page-about { @import "./pages/page-about.less"; }
|
|
||||||
body.cp-page-privacy { @import "./pages/page-privacy.less"; }
|
|
||||||
body.cp-page-features { @import "./pages/page-features.less"; }
|
|
||||||
body.cp-page-faq { @import "./pages/page-faq.less"; }
|
|
||||||
body.cp-page-terms { @import "./pages/page-terms.less"; }
|
|
||||||
|
|
||||||
// Set the HTML style for the apps which shouldn't have a body scrollbar
|
|
||||||
html.cp-app-noscroll {
|
|
||||||
@import "./include/app-noscroll.less";
|
|
||||||
.app-noscroll_main();
|
|
||||||
}
|
|
||||||
// Set the HTML style for printing slides
|
|
||||||
html.cp-app-print {
|
|
||||||
@import "./include/app-print.less";
|
|
||||||
.app-print_main();
|
|
||||||
}
|
|
||||||
|
|
||||||
body.cp-readonly .cp-hidden-if-readonly { display: none !important; }
|
|
||||||
|
|
||||||
body.cp-app-drive { @import "../../../drive/app-drive.less"; }
|
|
||||||
body.cp-app-pad { @import "../../../pad/app-pad.less"; }
|
|
||||||
body.cp-app-code { @import "../../../code/app-code.less"; }
|
|
||||||
body.cp-app-slide { @import "../../../slide/app-slide.less"; }
|
|
||||||
body.cp-app-file { @import "../../../file/app-file.less"; }
|
|
||||||
body.cp-app-filepicker { @import "../../../filepicker/app-filepicker.less"; }
|
|
||||||
body.cp-app-contacts { @import "../../../contacts/app-contacts.less"; }
|
|
||||||
body.cp-app-poll { @import "../../../poll/app-poll.less"; }
|
|
||||||
body.cp-app-whiteboard { @import "../../../whiteboard/app-whiteboard.less"; }
|
|
||||||
body.cp-app-todo { @import "../../../todo/app-todo.less"; }
|
|
||||||
body.cp-app-profile { @import "../../../profile/app-profile.less"; }
|
|
||||||
body.cp-app-settings { @import "../../../settings/app-settings.less"; }
|
|
||||||
body.cp-app-debug { @import "../../../debug/app-debug.less"; }
|
|
||||||
body.cp-app-worker { @import "../../../worker/app-worker.less"; }
|
|
||||||
body.cp-app-kanban { @import "../../../kanban/app-kanban.less"; }
|
|
||||||
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
@import (once) "../include/font.less";
|
@import (reference) "../include/font.less";
|
||||||
.font_neuropolitical();
|
|
||||||
.font_open-sans();
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
|
.font_main();
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
#cp-main {
|
#cp-main {
|
||||||
|
|||||||
@@ -1,115 +1,118 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-about {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
#cp-main {
|
|
||||||
background: #fff;
|
#cp-main {
|
||||||
}
|
|
||||||
.cp-about-intro {
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
background-image: url(/customize/bkabout.jpg);
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
.container {
|
|
||||||
color: #fff;
|
|
||||||
font-family: "Open Sans";
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
padding-top: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-container {
|
|
||||||
.row {
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
.cp-bio-avatar {
|
.cp-about-intro {
|
||||||
padding-right: 0;
|
padding-top: 3em;
|
||||||
@media (max-width: 991px) {
|
padding-bottom: 3em;
|
||||||
padding-right: 15px;
|
background-image: url(/customize/bkabout.jpg);
|
||||||
}
|
background-size: cover;
|
||||||
img {
|
background-repeat: no-repeat;
|
||||||
@media (max-width: 991px) {
|
background-position: center;
|
||||||
margin: 0 auto;
|
.container {
|
||||||
display: block;
|
color: #fff;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
h1 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
padding-top: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-bio-avatar-right {
|
.cp-container {
|
||||||
padding-right: 15px;
|
.row {
|
||||||
padding-left: 0;
|
background: #fff;
|
||||||
@media (max-width: 991px) {
|
}
|
||||||
padding-left: 15px;
|
.cp-bio-avatar {
|
||||||
|
padding-right: 0;
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
margin: 0 auto;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-bio-avatar-right {
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 0;
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.cp-develop-about {
|
||||||
.cp-develop-about {
|
.cp-icon-cent {
|
||||||
.cp-icon-cent {
|
width: 6rem;
|
||||||
width: 6rem;
|
background: #fff;
|
||||||
background: #fff;
|
border-radius: 50%;
|
||||||
border-radius: 50%;
|
height: 6rem;
|
||||||
height: 6rem;
|
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
||||||
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
margin: 0 auto;
|
||||||
margin: 0 auto;
|
background-image: url(/customize/code.svg);
|
||||||
background-image: url(/customize/code.svg);
|
background-repeat: no-repeat;
|
||||||
background-repeat: no-repeat;
|
margin-top: 1em;
|
||||||
margin-top: 1em;
|
margin-bottom: 1.5em;
|
||||||
margin-bottom: 1.5em;
|
background-position: 50%;
|
||||||
background-position: 50%;
|
background-size: 4rem;
|
||||||
background-size: 4rem;
|
}
|
||||||
|
h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1E1F1F;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h2 {
|
.cp-profile-det {
|
||||||
margin-top: 0;
|
padding-left: 30px;
|
||||||
font-weight: 600;
|
h3 {
|
||||||
color: #1E1F1F;
|
color: #1E1F1F;
|
||||||
margin-bottom: 1.5em;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
}
|
p {
|
||||||
.cp-profile-det {
|
color: #3F4141;
|
||||||
padding-left: 30px;
|
margin-bottom: 1em;
|
||||||
h3 {
|
}
|
||||||
color: #1E1F1F;
|
hr {
|
||||||
font-weight: 700;
|
margin-left: 0;
|
||||||
}
|
width: 15rem;
|
||||||
p {
|
border-top: 2px solid @cryptpad_color_blue;
|
||||||
color: #3F4141;
|
}
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
hr {
|
.cp-soc-media {
|
||||||
margin-left: 0;
|
font-size: 1.5em;
|
||||||
width: 15rem;
|
|
||||||
border-top: 2px solid @cryptpad_color_blue;
|
|
||||||
}
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.cp-soc-media {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: @cryptpad_color_blue;
|
|
||||||
padding-right: 1em;
|
|
||||||
display: inline-block;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
&:visited {
|
|
||||||
color: @cryptpad_color_blue;
|
color: @cryptpad_color_blue;
|
||||||
|
padding-right: 1em;
|
||||||
|
display: inline-block;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
&:visited {
|
||||||
|
color: @cryptpad_color_blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-contrib {
|
||||||
|
margin-top: 3em;
|
||||||
|
.cp-icon-cent {
|
||||||
|
background-image: url(/customize/source-branch.svg);
|
||||||
|
background-position: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-contrib {
|
.cp-margin-bot {
|
||||||
margin-top: 3em;
|
margin-bottom: 1.5em;
|
||||||
.cp-icon-cent {
|
|
||||||
background-image: url(/customize/source-branch.svg);
|
|
||||||
background-position: 60%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-margin-bot {
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,90 +1,92 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-contact {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
|
|
||||||
.fa {
|
.fa {
|
||||||
padding-right: 0.25em;
|
padding-right: 0.25em;
|
||||||
}
|
}
|
||||||
#cp-main {
|
#cp-main {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
.cp-container {
|
.cp-container {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
.cp-iconCont {
|
.cp-iconCont {
|
||||||
h4 {
|
h4 {
|
||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1.5em;
|
||||||
}
|
|
||||||
div {
|
|
||||||
.card {
|
|
||||||
padding: 4em 1em 0.5em 1em;
|
|
||||||
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
|
||||||
border-color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
&:hover, &:focus {
|
|
||||||
text-decoration: none;
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
@media (max-width: 1200px) and (min-width: 769px) {
|
|
||||||
min-height: 139px;
|
|
||||||
}
|
|
||||||
@media (max-width: 768px) and (min-width: 576px) {
|
|
||||||
min-height: 164px;
|
|
||||||
}
|
|
||||||
@media (max-width: 496px) {
|
|
||||||
min-height: 140px;
|
|
||||||
}
|
|
||||||
@media (max-width: 335px) {
|
|
||||||
min-height: 162px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&:nth-child(2) {
|
div {
|
||||||
.card {
|
.card {
|
||||||
background-image: url(/customize/images/twitter.svg);
|
padding: 4em 1em 0.5em 1em;
|
||||||
background-repeat: no-repeat;
|
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
||||||
background-position: 50% 10%;
|
border-color: #fff;
|
||||||
background-size: 3rem;
|
text-align: center;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
&:hover, &:focus {
|
||||||
|
text-decoration: none;
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
@media (max-width: 1200px) and (min-width: 769px) {
|
||||||
|
min-height: 139px;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) and (min-width: 576px) {
|
||||||
|
min-height: 164px;
|
||||||
|
}
|
||||||
|
@media (max-width: 496px) {
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
@media (max-width: 335px) {
|
||||||
|
min-height: 162px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
&:nth-child(2) {
|
||||||
&:nth-child(3) {
|
.card {
|
||||||
.card {
|
background-image: url(/customize/images/twitter.svg);
|
||||||
background-image: url(/customize/images/issue.svg);
|
background-repeat: no-repeat;
|
||||||
background-repeat: no-repeat;
|
background-position: 50% 10%;
|
||||||
background-position: 50% 10%;
|
background-size: 3rem;
|
||||||
background-size: 3rem;
|
}
|
||||||
}
|
}
|
||||||
}
|
&:nth-child(3) {
|
||||||
&:nth-child(4) {
|
.card {
|
||||||
.card {
|
background-image: url(/customize/images/issue.svg);
|
||||||
background-image: url(/customize/images/sayhi.svg);
|
background-repeat: no-repeat;
|
||||||
background-repeat: no-repeat;
|
background-position: 50% 10%;
|
||||||
background-position: 50% 10%;
|
background-size: 3rem;
|
||||||
background-size: 3rem;
|
}
|
||||||
}
|
}
|
||||||
}
|
&:nth-child(4) {
|
||||||
&:nth-child(5) {
|
.card {
|
||||||
.card {
|
background-image: url(/customize/images/sayhi.svg);
|
||||||
background-image: url(/customize/images/email.svg);
|
background-repeat: no-repeat;
|
||||||
background-repeat: no-repeat;
|
background-position: 50% 10%;
|
||||||
background-position: 50% 10%;
|
background-size: 3rem;
|
||||||
background-size: 3rem;
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(5) {
|
||||||
|
.card {
|
||||||
|
background-image: url(/customize/images/email.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50% 10%;
|
||||||
|
background-size: 3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.cp-contdet {
|
||||||
.cp-contdet {
|
padding-top: 3em;
|
||||||
padding-top: 3em;
|
padding-bottom: 3em;
|
||||||
padding-bottom: 3em;
|
background-image: url(/customize/images/bkcontact.jpg);
|
||||||
background-image: url(/customize/images/bkcontact.jpg);
|
background-size: cover;
|
||||||
background-size: cover;
|
background-repeat: no-repeat;
|
||||||
background-repeat: no-repeat;
|
background-position: center;
|
||||||
background-position: center;
|
h1 {
|
||||||
h1 {
|
font-weight: 700;
|
||||||
font-weight: 700;
|
color: #fff;
|
||||||
color: #fff;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,84 +1,86 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-faq {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
#cp-main {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.cp-faq {
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
background-image: url(/customize/images/cover-faq.jpg);
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
.container {
|
|
||||||
color: #fff;
|
|
||||||
font-family: "Open Sans";
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-faq-ques-det {
|
#cp-main {
|
||||||
.cp-faq-header {
|
background: #fff;
|
||||||
a {
|
}
|
||||||
padding: 0;
|
.cp-faq {
|
||||||
h4 {
|
padding-top: 3em;
|
||||||
margin-top: 1.5rem;
|
padding-bottom: 3em;
|
||||||
margin-bottom: 1.5rem;
|
background-image: url(/customize/images/cover-faq.jpg);
|
||||||
.cp-brand-font {
|
background-size: cover;
|
||||||
font-family: "Neuropolitical";
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
.container {
|
||||||
|
color: #fff;
|
||||||
|
font-family: "Open Sans";
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-faq-ques-det {
|
||||||
|
.cp-faq-header {
|
||||||
|
a {
|
||||||
|
padding: 0;
|
||||||
|
h4 {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
.cp-brand-font {
|
||||||
|
font-family: "Neuropolitical";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.cp-faq-container {
|
||||||
.cp-faq-container {
|
.cp-faq-questions-items {
|
||||||
.cp-faq-questions-items {
|
background: #3a84b6;
|
||||||
background: #3a84b6;
|
color: #fff;
|
||||||
color: #fff;
|
padding: 1rem 1rem 0.5rem 1rem;
|
||||||
padding: 1rem 1rem 0.5rem 1rem;
|
margin-bottom: 1rem;
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
.cp-faq-questions-q {
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
-webkit-touch-callout: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
&:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
}
|
||||||
&:after {
|
.cp-faq-questions-q {
|
||||||
content: '\f067';
|
padding: 0;
|
||||||
font-family: FontAwesome;
|
margin-bottom: 0.5rem;
|
||||||
font-weight: normal;
|
cursor: pointer;
|
||||||
font-style: normal;
|
-webkit-touch-callout: none;
|
||||||
float: right;
|
-webkit-user-select: none;
|
||||||
text-decoration: none;
|
-khtml-user-select: none;
|
||||||
font-size: 13px;
|
-moz-user-select: none;
|
||||||
line-height: 1.5;
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
&:after {
|
||||||
|
content: '\f067';
|
||||||
|
font-family: FontAwesome;
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
float: right;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.cp-faq-questions-q.active-faq {
|
||||||
.cp-faq-questions-q.active-faq {
|
&:after {
|
||||||
&:after {
|
content: '\f068';
|
||||||
content: '\f068';
|
}
|
||||||
}
|
}
|
||||||
|
.cp-faq-questions-a {
|
||||||
|
display: none;
|
||||||
|
padding: 0.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
.cp-faq-questions-a {
|
|
||||||
display: none;
|
|
||||||
padding: 0.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
background-color: #fff;
|
|
||||||
color: #212529;
|
|
||||||
}
|
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,86 +1,89 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-features {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
#cp-main {
|
|
||||||
background-color: #fff;
|
#cp-main {
|
||||||
}
|
background-color: #fff;
|
||||||
.cp_cont_features {
|
}
|
||||||
padding-top: 3em;
|
.cp_cont_features {
|
||||||
padding-bottom: 3em;
|
padding-top: 3em;
|
||||||
background-image: url('/customize/images/cover-features.jpg');
|
padding-bottom: 3em;
|
||||||
background-size: cover;
|
background-image: url('/customize/images/cover-features.jpg');
|
||||||
background-repeat: no-repeat;
|
background-size: cover;
|
||||||
background-position: center;
|
background-repeat: no-repeat;
|
||||||
h1 {
|
background-position: center;
|
||||||
font-weight: 700;
|
h1 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#cp-features-register {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.cp-features-register-button {
|
||||||
|
font-size: 20px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
background: @cryptpad_color_blue;
|
||||||
|
border: 2px solid @cryptpad_color_blue;
|
||||||
|
border-radius: 0;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
padding: 0.5em 1em;
|
||||||
}
|
}
|
||||||
}
|
.cp-features-web {
|
||||||
#cp-features-register {
|
.card {
|
||||||
text-align: center;
|
box-shadow: 0 5px 15px rgba(69, 145, 196, 0.3);
|
||||||
padding: 20px;
|
border: none;
|
||||||
}
|
}
|
||||||
.cp-features-register-button {
|
h3 {
|
||||||
font-size: 20px;
|
color: #fff;
|
||||||
color: #fff;
|
}
|
||||||
background: @cryptpad_color_blue;
|
.list-group {
|
||||||
border: 2px solid @cryptpad_color_blue;
|
li {
|
||||||
border-radius: 0;
|
&:before {
|
||||||
&:hover {
|
content: "\f00c";
|
||||||
transform: scale(1.05);
|
font-family: "FontAwesome";
|
||||||
cursor: pointer;
|
font-size: 14px;
|
||||||
}
|
color: @cryptpad_color_blue;
|
||||||
padding: 0.5em 1em;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
.cp-features-web {
|
}
|
||||||
.card {
|
div {
|
||||||
box-shadow: 0 5px 15px rgba(69, 145, 196, 0.3);
|
display: inline;
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.list-group {
|
|
||||||
li {
|
|
||||||
&:before {
|
|
||||||
content: "\f00c";
|
|
||||||
font-family: "FontAwesome";
|
|
||||||
font-size: 14px;
|
|
||||||
color: @cryptpad_color_blue;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div {
|
a.voted {
|
||||||
display: inline;
|
opacity: 0.6;
|
||||||
|
margin-left: 15px;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-group-item {
|
||||||
|
border-color: rgba(69, 145, 196, 0.125);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.voted {
|
.cp-anon-user {
|
||||||
opacity: 0.6;
|
.card-body {
|
||||||
margin-left: 15px;
|
background-color: @cryptpad_color_blue;
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.list-group-item {
|
.cp-regis-user {
|
||||||
border-color: rgba(69, 145, 196, 0.125);
|
@media (max-width:575px) {
|
||||||
}
|
margin-top: 3em;
|
||||||
}
|
}
|
||||||
.cp-anon-user {
|
.card-body {
|
||||||
.card-body {
|
&:first-of-type {
|
||||||
background-color: @cryptpad_color_blue;
|
background: #4591C4;
|
||||||
}
|
background: -webkit-linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
||||||
}
|
background: linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
||||||
.cp-regis-user {
|
}
|
||||||
@media (max-width:575px) {
|
|
||||||
margin-top: 3em;
|
|
||||||
}
|
|
||||||
.card-body {
|
|
||||||
&:first-of-type {
|
|
||||||
background: #4591C4;
|
|
||||||
background: -webkit-linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
|
||||||
background: linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,192 +1,193 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-index {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
|
|
||||||
@background_lighter: rgba(0,0,0,0.1);
|
@background_lighter: rgba(0,0,0,0.1);
|
||||||
@background_darker: rgba(0,0,0,0.4);
|
@background_darker: rgba(0,0,0,0.4);
|
||||||
#cp-main {
|
#cp-main {
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
background: linear-gradient( @background_darker, @background_lighter ), url('/customize/bg14.jpg');
|
background: linear-gradient( @background_darker, @background_lighter ), url('/customize/bg14.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
.container {
|
.container {
|
||||||
@media only screen and (max-device-width : 576px) {
|
@media only screen and (max-device-width : 576px) {
|
||||||
margin-top: 6em;
|
margin-top: 6em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
body {
|
||||||
body {
|
font-family: "Open Sans", Helvetica;
|
||||||
font-family: "Open Sans", Helvetica;
|
|
||||||
}
|
|
||||||
.cp-right {
|
|
||||||
.cp-register-btn {
|
|
||||||
padding: 0.5em 1em 0.7em 1em;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.cp-login-btn {
|
.cp-right {
|
||||||
color: #fff;
|
.cp-register-btn {
|
||||||
padding: 0.5em 1em 0.7em 1em;
|
padding: 0.5em 1em 0.7em 1em;
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-title {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
margin-top: 1.5em;
|
|
||||||
img {
|
|
||||||
height: 20vh;
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
margin-left: 0;
|
|
||||||
h1 {
|
|
||||||
font-family: "Neuropolitical";
|
|
||||||
//font-family: Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", Times, serif;
|
|
||||||
//font-family: "Raleway";
|
|
||||||
font-size: 45px;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
//font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
|
||||||
font-size: 20px;
|
|
||||||
//font-style: italic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navbar {
|
|
||||||
background: transparent;
|
|
||||||
width: 100%;
|
|
||||||
@media only screen and (max-device-width: 991px) {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
.navbar-brand {
|
|
||||||
background-image: url(/customize/CryptPad-white-logo.svg);
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #fff;
|
|
||||||
&:visited {
|
|
||||||
color: rgba(255,255,255,.9);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
.nav-link {
|
|
||||||
&:hover {
|
|
||||||
color: inherit;
|
|
||||||
transform: scale(1.05);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
.cp-register-btn {
|
|
||||||
border: 2px solid #fff;
|
border: 2px solid #fff;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-login-btn {
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.5em 1em 0.7em 1em;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.navbar-toggler {
|
.cp-title {
|
||||||
margin-top: 10px;
|
display: flex;
|
||||||
color: #fff;
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
img {
|
||||||
|
height: 20vh;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
margin-left: 0;
|
||||||
|
h1 {
|
||||||
|
font-family: "Neuropolitical";
|
||||||
|
//font-family: Garamond, Baskerville, "Baskerville Old Face", "Hoefler Text", "Times New Roman", Times, serif;
|
||||||
|
//font-family: "Raleway";
|
||||||
|
font-size: 45px;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
//font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||||
|
font-size: 20px;
|
||||||
|
//font-style: italic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.navbar {
|
||||||
@callout-padding: 15px;
|
background: transparent;
|
||||||
a:hover {
|
width: 100%;
|
||||||
text-decoration: none;
|
@media only screen and (max-device-width: 991px) {
|
||||||
}
|
margin-top: 0;
|
||||||
.bs-callout {
|
}
|
||||||
display: flex;
|
.navbar-brand {
|
||||||
align-items: stretch;
|
background-image: url(/customize/CryptPad-white-logo.svg);
|
||||||
margin: 25px 0;
|
}
|
||||||
background: rgba(255,255,255,0.6);
|
a {
|
||||||
color: black;
|
color: #fff;
|
||||||
transition: all .1s ease-in-out;
|
&:visited {
|
||||||
box-sizing: border-box;
|
color: rgba(255,255,255,.9);
|
||||||
height: 5em;
|
};
|
||||||
position: relative;
|
}
|
||||||
a {
|
.nav-link {
|
||||||
|
&:hover {
|
||||||
|
color: inherit;
|
||||||
|
transform: scale(1.05);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
.cp-register-btn {
|
||||||
|
border: 2px solid #fff;
|
||||||
|
}
|
||||||
|
.navbar-toggler {
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@callout-padding: 15px;
|
||||||
|
a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.bs-callout {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
margin: 25px 0;
|
||||||
|
background: rgba(255,255,255,0.6);
|
||||||
color: black;
|
color: black;
|
||||||
&:hover { text-decoration-line: none; }
|
transition: all .1s ease-in-out;
|
||||||
}
|
box-sizing: border-box;
|
||||||
div h4 {
|
height: 5em;
|
||||||
@media only screen and (min-device-width: 576px) and (max-device-width: 767px) {
|
position: relative;
|
||||||
font-size: 1.3em;
|
a {
|
||||||
|
color: black;
|
||||||
|
&:hover { text-decoration-line: none; }
|
||||||
|
}
|
||||||
|
div h4 {
|
||||||
|
@media only screen and (min-device-width: 576px) and (max-device-width: 767px) {
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
h4 {
|
||||||
h4 {
|
margin: 0;
|
||||||
margin: 0;
|
}
|
||||||
}
|
.cp-callout-more-moremsg,.cp-callout-more-lessmsg {
|
||||||
.cp-callout-more-moremsg,.cp-callout-more-lessmsg {
|
|
||||||
transform: none !important;
|
|
||||||
}
|
|
||||||
.bs-callout div {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: 5em;
|
|
||||||
}
|
|
||||||
.bs-callout+.bs-callout {
|
|
||||||
margin-top: -5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bs-callout:hover {
|
|
||||||
//color: white;
|
|
||||||
transform: scale(1.05);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.bs-callout:hover.cp-callout-more {
|
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
}
|
}
|
||||||
.bs-callout .fa {
|
.bs-callout div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 2em;
|
justify-content: center;
|
||||||
padding-left: 0.57em;
|
height: 100%;
|
||||||
width: 2em;
|
position: absolute;
|
||||||
transition: width 0.1s;
|
left: 5em;
|
||||||
color: #fff;
|
}
|
||||||
}
|
.bs-callout+.bs-callout {
|
||||||
.cp-callout-pad .fa { background-color: @colortheme_pad-bg; }
|
margin-top: -5px;
|
||||||
.cp-callout-code .fa { background-color: @colortheme_code-bg; }
|
}
|
||||||
.cp-callout-slide .fa { background-color: @colortheme_slide-bg; }
|
|
||||||
.cp-callout-poll .fa { background-color: @colortheme_poll-bg; }
|
.bs-callout:hover {
|
||||||
.cp-callout-kanban .fa { background-color: @colortheme_kanban-bg; }
|
//color: white;
|
||||||
.cp-callout-whiteboard .fa { background-color: @colortheme_whiteboard-bg; }
|
transform: scale(1.05);
|
||||||
.cp-callout-recent .fa { background-color: @colortheme_drive-bg; }
|
cursor: pointer;
|
||||||
.cp-hidden { display: none !important; }
|
}
|
||||||
.cp-callout-more {
|
.bs-callout:hover.cp-callout-more {
|
||||||
display: inline-block;
|
transform: none !important;
|
||||||
align-content: center;
|
}
|
||||||
height: 2em;
|
.bs-callout .fa {
|
||||||
border-radius: 1em;
|
display: flex;
|
||||||
margin-left: auto;
|
align-items: center;
|
||||||
margin-right: auto;
|
font-size: 2em;
|
||||||
margin-top: 0;
|
padding-left: 0.57em;
|
||||||
background: none;
|
width: 2em;
|
||||||
width: 100%;
|
transition: width 0.1s;
|
||||||
div {
|
|
||||||
.infopages_link();
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
.fa {
|
}
|
||||||
font-size: inherit;
|
.cp-callout-pad .fa { background-color: @colortheme_pad-bg; }
|
||||||
padding: 0;
|
.cp-callout-code .fa { background-color: @colortheme_code-bg; }
|
||||||
width: 1em;
|
.cp-callout-slide .fa { background-color: @colortheme_slide-bg; }
|
||||||
padding-left: 5px;
|
.cp-callout-poll .fa { background-color: @colortheme_poll-bg; }
|
||||||
|
.cp-callout-kanban .fa { background-color: @colortheme_kanban-bg; }
|
||||||
|
.cp-callout-whiteboard .fa { background-color: @colortheme_whiteboard-bg; }
|
||||||
|
.cp-callout-recent .fa { background-color: @colortheme_drive-bg; }
|
||||||
|
.cp-hidden { display: none !important; }
|
||||||
|
.cp-callout-more {
|
||||||
|
display: inline-block;
|
||||||
|
align-content: center;
|
||||||
|
height: 2em;
|
||||||
|
border-radius: 1em;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-top: 0;
|
||||||
|
background: none;
|
||||||
|
width: 100%;
|
||||||
|
div {
|
||||||
|
.infopages_link();
|
||||||
|
color: #fff;
|
||||||
|
.fa {
|
||||||
|
font-size: inherit;
|
||||||
|
padding: 0;
|
||||||
|
width: 1em;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 576px) and (max-width: 767px) {
|
||||||
|
.container {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
div#cp-main.cp-page-index .cp-topbar .navbar-toggler-left {
|
||||||
|
left: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (min-width: 576px) and (max-width: 767px) {
|
|
||||||
.container {
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
div#cp-main.cp-page-index .cp-topbar .navbar-toggler-left {
|
|
||||||
left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +1,71 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
@import (once) "../include/alertify.less";
|
@import (reference) "../include/alertify.less";
|
||||||
@import (once) "../include/checkmark.less";
|
@import (reference) "../include/checkmark.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-login {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
.alertify_main();
|
.alertify_main();
|
||||||
.checkmark_main(20px);
|
.checkmark_main(20px);
|
||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
.extra {
|
.extra {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-container {
|
|
||||||
#data {
|
|
||||||
background: #4591C4;
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 7em;
|
|
||||||
padding-left: 30px;
|
|
||||||
padding-right: 30px;
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-weight: 700;
|
|
||||||
color: @cryptpad_header_col;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#userForm {
|
.cp-container {
|
||||||
padding-top: 3em;
|
#data {
|
||||||
padding-bottom: 2em;
|
background: #4591C4;
|
||||||
.form-control {
|
padding-top: 3em;
|
||||||
border-radius: 0;
|
padding-bottom: 7em;
|
||||||
color: @cryptpad_text_col;
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
p {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: @cryptpad_header_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#userForm {
|
||||||
|
padding-top: 3em;
|
||||||
|
padding-bottom: 2em;
|
||||||
|
.form-control {
|
||||||
|
border-radius: 0;
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
margin-top: 1em;
|
||||||
|
&:focus {
|
||||||
|
border-color: @cryptpad_color_blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.checkbox-container {
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.align-items-center {
|
||||||
|
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.extra {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
&:focus {
|
.login {
|
||||||
border-color: @cryptpad_color_blue;
|
background: @cryptpad_color_blue;
|
||||||
}
|
color: #fff;
|
||||||
}
|
padding: 10px;
|
||||||
.checkbox-container {
|
border-radius: 0;
|
||||||
color: @cryptpad_text_col;
|
&:hover {
|
||||||
}
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
.align-items-center {
|
|
||||||
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.extra {
|
|
||||||
margin-top: 1em;
|
|
||||||
.login {
|
|
||||||
background: @cryptpad_color_blue;
|
|
||||||
color: #fff;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 0;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.cp-container {
|
||||||
|
padding-top: 3em;
|
||||||
|
min-height: 66vh;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.cp-container {
|
|
||||||
padding-top: 3em;
|
|
||||||
min-height: 66vh;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,48 +1,51 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-privacy {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
#cp-main {
|
|
||||||
background: #fff;
|
#cp-main {
|
||||||
}
|
background: #fff;
|
||||||
.cp-privacy-top {
|
}
|
||||||
padding-top: 3em;
|
.cp-privacy-top {
|
||||||
padding-bottom: 3em;
|
padding-top: 3em;
|
||||||
background-image: url(/customize/images/cover-privacy.jpg);
|
padding-bottom: 3em;
|
||||||
background-size: cover;
|
background-image: url(/customize/images/cover-privacy.jpg);
|
||||||
background-repeat: no-repeat;
|
background-size: cover;
|
||||||
background-position: center;
|
background-repeat: no-repeat;
|
||||||
.container {
|
background-position: center;
|
||||||
color: #fff;
|
.container {
|
||||||
font-family: "Open Sans";
|
color: #fff;
|
||||||
h1 {
|
font-family: "Open Sans";
|
||||||
|
h1 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-privacy {
|
||||||
|
background-image: url(/customize/CryptPadlogo_op5.svg);
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
hr {
|
||||||
|
margin-left: 0;
|
||||||
|
width: 15rem;
|
||||||
|
border-top: 2px solid #4591C4;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
color: #1E1F1F;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
a {
|
|
||||||
color: #fff;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
p {
|
p {
|
||||||
padding-top: 1em;
|
color: #3F4141;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.cp-privacy {
|
|
||||||
background-image: url(/customize/CryptPadlogo_op5.svg);
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
hr {
|
|
||||||
margin-left: 0;
|
|
||||||
width: 15rem;
|
|
||||||
border-top: 2px solid #4591C4;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
color: #1E1F1F;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: #3F4141;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,139 +1,142 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
@import (once) "../include/alertify.less";
|
@import (reference) "../include/alertify.less";
|
||||||
@import (once) "../include/checkmark.less";
|
@import (reference) "../include/checkmark.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-register {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
.alertify_main();
|
|
||||||
.checkmark_main(20px);
|
|
||||||
|
|
||||||
.cp-container {
|
.alertify_main();
|
||||||
.form-group {
|
.checkmark_main(20px);
|
||||||
.checkbox-container {
|
|
||||||
&:nth-of-type(1) {
|
.cp-container {
|
||||||
margin-top: 2em;
|
.form-group {
|
||||||
|
.checkbox-container {
|
||||||
|
&:nth-of-type(1) {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
&:last-of-type {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
&:last-of-type {
|
#register {
|
||||||
margin-bottom: 1em;
|
&.btn {
|
||||||
|
padding: .5rem .5rem;
|
||||||
|
}
|
||||||
|
margin-top: 16px;
|
||||||
|
font-size: 1.25em;
|
||||||
|
min-width: 30%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#register {
|
padding-bottom: 3em;
|
||||||
&.btn {
|
min-height: 5vh;
|
||||||
padding: .5rem .5rem;
|
}
|
||||||
}
|
.alertify {
|
||||||
margin-top: 16px;
|
// workaround for alertify making empty p
|
||||||
font-size: 1.25em;
|
p:empty {
|
||||||
min-width: 30%;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
padding-bottom: 3em;
|
.cp-register-wel {
|
||||||
min-height: 5vh;
|
padding-top: 6em;
|
||||||
}
|
padding-bottom: 20em;
|
||||||
.alertify {
|
background-image: url(/customize/bkregister.jpg);
|
||||||
// workaround for alertify making empty p
|
background-size: cover;
|
||||||
p:empty {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-register-wel {
|
|
||||||
padding-top: 6em;
|
|
||||||
padding-bottom: 20em;
|
|
||||||
background-image: url(/customize/bkregister.jpg);
|
|
||||||
background-size: cover;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 1px 5px rgba(0,0,0,.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-register-det {
|
|
||||||
margin-top: -7em;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
|
||||||
|
|
||||||
#data {
|
|
||||||
// Old browsers
|
|
||||||
background: #4591C4;
|
|
||||||
|
|
||||||
// Chrome 10-25, Safari 5.1-6
|
|
||||||
background: -webkit-linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
|
||||||
|
|
||||||
// W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+
|
|
||||||
background: linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
|
||||||
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 7em;
|
|
||||||
padding-left: 30px;
|
|
||||||
padding-right: 30px;
|
|
||||||
p {
|
|
||||||
color: #fff;
|
|
||||||
li {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.fa {
|
|
||||||
font-size: 1.5em;
|
|
||||||
padding-right: 10px;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#userForm {
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 2em;
|
|
||||||
.form-control {
|
|
||||||
border-radius: 0;
|
|
||||||
color: @cryptpad_text_col;
|
|
||||||
margin-top: 1em;
|
|
||||||
&:focus {
|
|
||||||
border-color: @cryptpad_color_blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.checkbox-container {
|
|
||||||
color: @cryptpad_text_col;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-login-register {
|
|
||||||
color: @cryptpad_color_blue;
|
|
||||||
background: #fff;
|
|
||||||
border: 2px solid @cryptpad_color_blue;
|
|
||||||
border-radius: 0;
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-register-test {
|
|
||||||
margin-top: 3em;
|
|
||||||
hr {
|
|
||||||
width: 15rem;
|
|
||||||
border-top: 2px solid @cryptpad_color_blue;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 2em;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
.cp-test-source {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.test-details {
|
|
||||||
padding-left: 4em;
|
|
||||||
background-image: url(/customize/testimonial.svg);
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: left top;
|
background-position: center;
|
||||||
background-size: 3em;
|
h1 {
|
||||||
color: @cryptpad_text_col;
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 1px 5px rgba(0,0,0,.2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cp-register-det {
|
||||||
|
margin-top: -7em;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 5px 15px rgba(69,145,196, 0.3);
|
||||||
|
|
||||||
|
#data {
|
||||||
|
// Old browsers
|
||||||
|
background: #4591C4;
|
||||||
|
|
||||||
|
// Chrome 10-25, Safari 5.1-6
|
||||||
|
background: -webkit-linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
||||||
|
|
||||||
|
// W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+
|
||||||
|
background: linear-gradient(to right, #FF7C4F, #4592C4); // lesshint duplicateProperty: false
|
||||||
|
|
||||||
|
padding-top: 3em;
|
||||||
|
padding-bottom: 7em;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 30px;
|
||||||
|
p {
|
||||||
|
color: #fff;
|
||||||
|
li {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.fa {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#userForm {
|
||||||
|
padding-top: 3em;
|
||||||
|
padding-bottom: 2em;
|
||||||
|
.form-control {
|
||||||
|
border-radius: 0;
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
margin-top: 1em;
|
||||||
|
&:focus {
|
||||||
|
border-color: @cryptpad_color_blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.checkbox-container {
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-login-register {
|
||||||
|
color: @cryptpad_color_blue;
|
||||||
|
background: #fff;
|
||||||
|
border: 2px solid @cryptpad_color_blue;
|
||||||
|
border-radius: 0;
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-register-test {
|
||||||
|
margin-top: 3em;
|
||||||
|
hr {
|
||||||
|
width: 15rem;
|
||||||
|
border-top: 2px solid @cryptpad_color_blue;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.cp-test-source {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
.test-details {
|
||||||
|
padding-left: 4em;
|
||||||
|
background-image: url(/customize/testimonial.svg);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: left top;
|
||||||
|
background-size: 3em;
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#cp-main {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#cp-main {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
|
&.cp-page-terms {
|
||||||
|
.infopages_main();
|
||||||
|
}
|
||||||
|
|
||||||
.infopages_main();
|
|
||||||
.infopages_topbar();
|
|
||||||
|
|||||||
@@ -1,43 +1,45 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (reference) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme-all.less";
|
@import (reference) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
&.cp-page-what-is-cryptpad {
|
||||||
.infopages_topbar();
|
.infopages_main();
|
||||||
|
|
||||||
.cp-what-is {
|
.cp-what-is {
|
||||||
|
padding-top: 3em;
|
||||||
|
padding-bottom: 3em;
|
||||||
|
background-image: url(/customize/bkwhat.jpg);
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
color: #fff;
|
||||||
|
h1 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#cp-main {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.cp-container {
|
||||||
padding-top: 3em;
|
padding-top: 3em;
|
||||||
padding-bottom: 3em;
|
padding-bottom: 3em;
|
||||||
background-image: url(/customize/bkwhat.jpg);
|
h2 {
|
||||||
background-size: cover;
|
margin-top: 0;
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
color: #fff;
|
|
||||||
h1 {
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
color: @cryptpad_header_col;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: @cryptpad_text_col;
|
||||||
|
}
|
||||||
|
#zeroknowledge {
|
||||||
|
width: 65%;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#cp-main {
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
.cp-container {
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
font-weight: 700;
|
|
||||||
color: @cryptpad_header_col;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: @cryptpad_text_col;
|
|
||||||
}
|
|
||||||
#zeroknowledge {
|
|
||||||
width: 65%;
|
|
||||||
}
|
|
||||||
.row {
|
|
||||||
margin-bottom: 1.5em;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,45 @@
|
|||||||
# CryptPad Styling
|
# CryptPad Styling
|
||||||
|
|
||||||
How it works:
|
## Linking Less/CSS
|
||||||
* In this example, we use the index page, for each page we will have a corresponding class name and a corresponding less file.
|
|
||||||
* The index page has a main div containing everything `<div id="cp-main" class="cp-page-index">`
|
In order to keep the amount of CSS generated under control, we use "linking", via the LessLoader.
|
||||||
* There is a corresponding less file called `less2/pages/page-index.less`
|
This makes use of CSS variables in order to work. The old solution was to put all of the content into less mixins
|
||||||
* Finally there is a corresponding line in main.less which imports that less file: `div#main.cp-page-index { @import "./pages/page-index.less"; }`
|
which would be used inside of the scope where they should be, but this caused a state explosion because each app needed
|
||||||
* cp-page-index class means:
|
essentially the same mixins. However, these mixins had arguments such as colors which were different per-app.
|
||||||
* cp -> cryptpad
|
|
||||||
* page -> this is a style for accessing a page's less file
|
The new solution is to set CSS variables for the arguments (like color) and then put the bulk of the less at the global
|
||||||
* index -> the name of the page and of the less file (page-index.less)
|
scope. When you include a dependency, the following happens:
|
||||||
* And everything which is standardized across pages is included from `page-index.less` as variables and mixins.
|
|
||||||
|
1. You `@include (reference) './include/dependency.less`. The (reference) argument which means it will not emit CSS,
|
||||||
|
this is important because otherwise all of the dependencies of your app's less file would end up bundled with it, the
|
||||||
|
state explosion problem.
|
||||||
|
2. You invoke `.dependency_main(@arg1 @arg2)` inside of the scope you want it in, the name `dependency_main` is a
|
||||||
|
convention, all less variables, mixins, or CSS variables which a file creates should be prefixed with the name of the
|
||||||
|
file (in this case, "dependency").
|
||||||
|
3. The mixin `.dependency_main` does a couple of things:
|
||||||
|
* First, it sets a CSS variable called `--LessLoader_require`, this is a special variable which the browser does not
|
||||||
|
use, the only objective of this variable is to inform LessLoader that another file is needed. To do this, there is a
|
||||||
|
helper function (also specified in LessLoader.js) called `LessLoader_currentFile()`. The syntax is:
|
||||||
|
`--LessLoader_require: LessLoader_currentFile();` and in the CSS, this outputs something like:
|
||||||
|
`--LessLoader_require: "/customize/src/less2/include/dependency.less?ver=2.4.0-1531572157592";`
|
||||||
|
* Secondly, it sets browser variables for it's arguments, making sure to avoid namespace collisions:
|
||||||
|
`--dependency-arg1: @arg1;`, `--dependency-arg2: @arg2;`. Sometimes a less transformation needs to be done on a
|
||||||
|
variable, unfortunately in this case the transformation must be done here and the transformed variable must be output.
|
||||||
|
`--dependency-arg1-l10: lighten(@arg1, 10%);`.
|
||||||
|
4. After less processing is completed, the LessLoader caches the result of parsing, then scans the it for instances of
|
||||||
|
`--LessLoader_require` variable and then processes them, but it does this separately. So even if dependency.less is
|
||||||
|
required many times, it will only be processed by the less interpreter once.
|
||||||
|
|
||||||
|
## Other convensions
|
||||||
|
|
||||||
Rules:
|
|
||||||
* All of our new classes and ids should start with `cp-`.
|
* All of our new classes and ids should start with `cp-`.
|
||||||
* You may make as many files as you need, for different purposes, but they can only contain mixins and variables.
|
* The document body has a class on it depending on the app/page, app classes begin with `cp-app-` and page classes begin
|
||||||
|
with `cp-page-`.
|
||||||
|
* Custom classes ought to begin with `cp-` and the name of the file where the rules are written for them (see help.less as
|
||||||
|
an example of doing the right thing).
|
||||||
|
* Since the include files generate CSS and the app cannot control the scope which it's run at, be considerate avoid
|
||||||
|
making an include file which changes something significant (like making a rule for `li`). help.less is an excellent example
|
||||||
|
of doing this well, infopages.less is the worst example (fortunately it doesn't get included in any of the apps).
|
||||||
* All mixins and variables must be prefixed with the name of the file where they're defined and and underscore.
|
* All mixins and variables must be prefixed with the name of the file where they're defined and and underscore.
|
||||||
* e.g. `@colortheme_toolbar-poll-bg: #006304;` defined in `colortheme.less`
|
* e.g. `@colortheme_toolbar-poll-bg: #006304;` defined in `colortheme.less`
|
||||||
* All mixin / variable files go in an `/include/` directory.
|
* All mixin / variable files go in an `/include/` directory.
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ $(function () {
|
|||||||
|
|
||||||
window.Tether = function () {};
|
window.Tether = function () {};
|
||||||
require([
|
require([
|
||||||
'less!/customize/src/less2/main.less',
|
'less!/customize/src/less2/pages/page-' + css + '.less',
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css'
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css'
|
||||||
], function () {
|
], function () {
|
||||||
$body.append($main);
|
$body.append($main);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -386,6 +386,7 @@ define(function () {
|
|||||||
out.fm_newFolder = "Nouveau dossier";
|
out.fm_newFolder = "Nouveau dossier";
|
||||||
out.fm_newFile = "Nouveau pad";
|
out.fm_newFile = "Nouveau pad";
|
||||||
out.fm_folder = "Dossier";
|
out.fm_folder = "Dossier";
|
||||||
|
out.fm_sharedFolder = "Dossier partagé";
|
||||||
out.fm_folderName = "Nom du dossier";
|
out.fm_folderName = "Nom du dossier";
|
||||||
out.fm_numberOfFolders = "# de dossiers";
|
out.fm_numberOfFolders = "# de dossiers";
|
||||||
out.fm_numberOfFiles = "# de fichiers";
|
out.fm_numberOfFiles = "# de fichiers";
|
||||||
@@ -435,6 +436,7 @@ define(function () {
|
|||||||
out.fm_viewListButton = "Liste";
|
out.fm_viewListButton = "Liste";
|
||||||
out.fm_viewGridButton = "Grille";
|
out.fm_viewGridButton = "Grille";
|
||||||
out.fm_renamedPad = "Vous avez renommé ce pad dans votre Drive. Son titre est:<br><b>{0}</b>";
|
out.fm_renamedPad = "Vous avez renommé ce pad dans votre Drive. Son titre est:<br><b>{0}</b>";
|
||||||
|
out.fm_canBeShared = "Ce dossier peut être partagé";
|
||||||
out.fm_prop_tagsList = "Mots-clés";
|
out.fm_prop_tagsList = "Mots-clés";
|
||||||
out.fm_burnThisDriveButton = "Effacer toutes les informations stockées par CryptPad dans votre navigateur";
|
out.fm_burnThisDriveButton = "Effacer toutes les informations stockées par CryptPad dans votre navigateur";
|
||||||
out.fm_burnThisDrive = "Êtes-vous sûr de vouloir supprimmer tout ce qui est stocké par CryptPad dans votre navigateur ?<br>" +
|
out.fm_burnThisDrive = "Êtes-vous sûr de vouloir supprimmer tout ce qui est stocké par CryptPad dans votre navigateur ?<br>" +
|
||||||
@@ -444,8 +446,11 @@ define(function () {
|
|||||||
out.fm_deletedPads = "Ces pads n'existent plus sur le serveur, ils ont été supprimés de votre CryptDrive: {0}";
|
out.fm_deletedPads = "Ces pads n'existent plus sur le serveur, ils ont été supprimés de votre CryptDrive: {0}";
|
||||||
out.fm_tags_name = "Mot-clé";
|
out.fm_tags_name = "Mot-clé";
|
||||||
out.fm_tags_used = "Nombre d'utilisations";
|
out.fm_tags_used = "Nombre d'utilisations";
|
||||||
|
out.fm_restoreDrive = "Restauration de votre CryptDrive à une version antérieure. Pour de meilleurs résultats, veuillez éviter de modifier votre CryptDrive avant que cette restauration ne soit terminée.";
|
||||||
|
out.fm_moveNestedSF = "Vous ne pouvez pas placer un dossier partagé dans un autre. Le dossier {0} n'a pas été déplacé.";
|
||||||
// File - Context menu
|
// File - Context menu
|
||||||
out.fc_newfolder = "Nouveau dossier";
|
out.fc_newfolder = "Nouveau dossier";
|
||||||
|
out.fc_newsharedfolder = "Nouveau dossier partagé";
|
||||||
out.fc_rename = "Renommer";
|
out.fc_rename = "Renommer";
|
||||||
out.fc_open = "Ouvrir";
|
out.fc_open = "Ouvrir";
|
||||||
out.fc_open_ro = "Ouvrir (lecture seule)";
|
out.fc_open_ro = "Ouvrir (lecture seule)";
|
||||||
@@ -453,12 +458,13 @@ define(function () {
|
|||||||
out.fc_delete_owned = "Supprimer du serveur";
|
out.fc_delete_owned = "Supprimer du serveur";
|
||||||
out.fc_restore = "Restaurer";
|
out.fc_restore = "Restaurer";
|
||||||
out.fc_remove = "Supprimer de votre CryptDrive";
|
out.fc_remove = "Supprimer de votre CryptDrive";
|
||||||
|
out.fc_remove_sharedfolder = "Supprimer";
|
||||||
out.fc_empty = "Vider la corbeille";
|
out.fc_empty = "Vider la corbeille";
|
||||||
out.fc_prop = "Propriétés";
|
out.fc_prop = "Propriétés";
|
||||||
out.fc_hashtag = "Mots-clés";
|
out.fc_hashtag = "Mots-clés";
|
||||||
out.fc_sizeInKilobytes = "Taille en kilo-octets";
|
out.fc_sizeInKilobytes = "Taille en kilo-octets";
|
||||||
// fileObject.js (logs)
|
// fileObject.js (logs)
|
||||||
out.fo_moveUnsortedError = "La liste des éléments non triés ne peut pas contenir de dossiers.";
|
out.fo_moveUnsortedError = "La liste des modèles ne peut pas contenir de dossiers.";
|
||||||
out.fo_existingNameError = "Ce nom est déjà utilisé dans ce répertoire. Veuillez en choisir un autre.";
|
out.fo_existingNameError = "Ce nom est déjà utilisé dans ce répertoire. Veuillez en choisir un autre.";
|
||||||
out.fo_moveFolderToChildError = "Vous ne pouvez pas déplacer un dossier dans un de ses descendants";
|
out.fo_moveFolderToChildError = "Vous ne pouvez pas déplacer un dossier dans un de ses descendants";
|
||||||
out.fo_unableToRestore = "Impossible de restaurer ce fichier à son emplacement d'origine. Vous pouvez essayer de le déplacer à un nouvel emplacement.";
|
out.fo_unableToRestore = "Impossible de restaurer ce fichier à son emplacement d'origine. Vous pouvez essayer de le déplacer à un nouvel emplacement.";
|
||||||
@@ -606,6 +612,7 @@ define(function () {
|
|||||||
out.settings_changePasswordConfirm = "Êtes-vous sûr de vouloir changer votre mot de passe ? Vous devrez vous reconnecter sur tous vos appareils.";
|
out.settings_changePasswordConfirm = "Êtes-vous sûr de vouloir changer votre mot de passe ? Vous devrez vous reconnecter sur tous vos appareils.";
|
||||||
out.settings_changePasswordError = "Une erreur est survenue. Si vous n'êtes plus en mesure de vous connecter à votre compte utilisateur ou de changer votre mot de passe, veuillez contacter l'administrateur de votre CryptPad.";
|
out.settings_changePasswordError = "Une erreur est survenue. Si vous n'êtes plus en mesure de vous connecter à votre compte utilisateur ou de changer votre mot de passe, veuillez contacter l'administrateur de votre CryptPad.";
|
||||||
out.settings_changePasswordPending = "Votre mot de passe est en train d'être modifié. Veuillez ne pas fermer ou recharger cette page avant que le traitement soit terminé.";
|
out.settings_changePasswordPending = "Votre mot de passe est en train d'être modifié. Veuillez ne pas fermer ou recharger cette page avant que le traitement soit terminé.";
|
||||||
|
out.settings_changePasswordNewPasswordSameAsOld = "Votre nouveau mot de passe doit être différent de votre mot de passe actuel.";
|
||||||
|
|
||||||
out.upload_title = "Hébergement de fichiers";
|
out.upload_title = "Hébergement de fichiers";
|
||||||
out.upload_modal_title = "Options d'importation du fichier";
|
out.upload_modal_title = "Options d'importation du fichier";
|
||||||
@@ -1161,5 +1168,14 @@ define(function () {
|
|||||||
out.loading_drive_2 = "Mise à jour du format des données";
|
out.loading_drive_2 = "Mise à jour du format des données";
|
||||||
out.loading_drive_3 = "Vérification de l'intégrité des données";
|
out.loading_drive_3 = "Vérification de l'intégrité des données";
|
||||||
|
|
||||||
|
// Shared folders
|
||||||
|
out.sharedFolders_forget = "Ce pad est stocké uniquement dans un dossier partagé. Vous ne pouvez pas le déplacer dans votre corbeille. Si vous souhaitez le supprimer, vous pouvez utiliser l'application CryptDrive.";
|
||||||
|
out.sharedFolders_duplicate = "Certains pads que vous essayez de déplacer sont déjà partagés dans le dossier de destination.";
|
||||||
|
out.sharedFolders_create = "Créer un dossier partagé";
|
||||||
|
out.sharedFolders_create_name = "Nom du dossier";
|
||||||
|
out.sharedFolders_create_owned = "Être propriétaire du dossier";
|
||||||
|
out.sharedFolders_create_password = "Mot de passe du dossier";
|
||||||
|
out.sharedFolders_share = "Partager cette URL avec d'autres utilisateurs enregistrés leur donne accès au dossier partagé. Une fois l'URL ouverte, le dossier partagé sera ajouté au répertoire racine de leur CryptDrive.";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -387,6 +387,7 @@ define(function () {
|
|||||||
out.fm_newFolder = "New folder";
|
out.fm_newFolder = "New folder";
|
||||||
out.fm_newFile = "New pad";
|
out.fm_newFile = "New pad";
|
||||||
out.fm_folder = "Folder";
|
out.fm_folder = "Folder";
|
||||||
|
out.fm_sharedFolder = "Shared folder";
|
||||||
out.fm_folderName = "Folder name";
|
out.fm_folderName = "Folder name";
|
||||||
out.fm_numberOfFolders = "# of folders";
|
out.fm_numberOfFolders = "# of folders";
|
||||||
out.fm_numberOfFiles = "# of files";
|
out.fm_numberOfFiles = "# of files";
|
||||||
@@ -436,6 +437,7 @@ define(function () {
|
|||||||
out.fm_viewListButton = "List view";
|
out.fm_viewListButton = "List view";
|
||||||
out.fm_viewGridButton = "Grid view";
|
out.fm_viewGridButton = "Grid view";
|
||||||
out.fm_renamedPad = "You've set a custom name for this pad. Its shared title is:<br><b>{0}</b>";
|
out.fm_renamedPad = "You've set a custom name for this pad. Its shared title is:<br><b>{0}</b>";
|
||||||
|
out.fm_canBeShared = "This folder can be shared";
|
||||||
out.fm_prop_tagsList = "Tags";
|
out.fm_prop_tagsList = "Tags";
|
||||||
out.fm_burnThisDriveButton = "Erase all information stored by CryptPad in your browser";
|
out.fm_burnThisDriveButton = "Erase all information stored by CryptPad in your browser";
|
||||||
out.fm_burnThisDrive = "Are you sure you want to remove everything stored by CryptPad in your browser?<br>" +
|
out.fm_burnThisDrive = "Are you sure you want to remove everything stored by CryptPad in your browser?<br>" +
|
||||||
@@ -445,8 +447,11 @@ define(function () {
|
|||||||
out.fm_deletedPads = "These pads no longer exist on the server, they've been removed from your CryptDrive: {0}";
|
out.fm_deletedPads = "These pads no longer exist on the server, they've been removed from your CryptDrive: {0}";
|
||||||
out.fm_tags_name = "Tag name";
|
out.fm_tags_name = "Tag name";
|
||||||
out.fm_tags_used = "Number of uses";
|
out.fm_tags_used = "Number of uses";
|
||||||
|
out.fm_restoreDrive = "Resetting your drive to an earlier state. For best results, avoid making changes to your drive until this process is complete.";
|
||||||
|
out.fm_moveNestedSF = "You can't place one shared folder within another. The folder {0} was not moved.";
|
||||||
// File - Context menu
|
// File - Context menu
|
||||||
out.fc_newfolder = "New folder";
|
out.fc_newfolder = "New folder";
|
||||||
|
out.fc_newsharedfolder = "New shared folder";
|
||||||
out.fc_rename = "Rename";
|
out.fc_rename = "Rename";
|
||||||
out.fc_open = "Open";
|
out.fc_open = "Open";
|
||||||
out.fc_open_ro = "Open (read-only)";
|
out.fc_open_ro = "Open (read-only)";
|
||||||
@@ -454,12 +459,13 @@ define(function () {
|
|||||||
out.fc_delete_owned = "Delete from the server";
|
out.fc_delete_owned = "Delete from the server";
|
||||||
out.fc_restore = "Restore";
|
out.fc_restore = "Restore";
|
||||||
out.fc_remove = "Remove from your CryptDrive";
|
out.fc_remove = "Remove from your CryptDrive";
|
||||||
|
out.fc_remove_sharedfolder = "Remove";
|
||||||
out.fc_empty = "Empty the trash";
|
out.fc_empty = "Empty the trash";
|
||||||
out.fc_prop = "Properties";
|
out.fc_prop = "Properties";
|
||||||
out.fc_hashtag = "Tags";
|
out.fc_hashtag = "Tags";
|
||||||
out.fc_sizeInKilobytes = "Size in Kilobytes";
|
out.fc_sizeInKilobytes = "Size in Kilobytes";
|
||||||
// fileObject.js (logs)
|
// fileObject.js (logs)
|
||||||
out.fo_moveUnsortedError = "You can't move a folder to the list of unsorted pads";
|
out.fo_moveUnsortedError = "You can't move a folder to the list of templates";
|
||||||
out.fo_existingNameError = "Name already used in that directory. Please choose another one.";
|
out.fo_existingNameError = "Name already used in that directory. Please choose another one.";
|
||||||
out.fo_moveFolderToChildError = "You can't move a folder into one of its descendants";
|
out.fo_moveFolderToChildError = "You can't move a folder into one of its descendants";
|
||||||
out.fo_unableToRestore = "Unable to restore that file to its original location. You can try to move it to a new location.";
|
out.fo_unableToRestore = "Unable to restore that file to its original location. You can try to move it to a new location.";
|
||||||
@@ -615,6 +621,7 @@ define(function () {
|
|||||||
out.settings_changePasswordConfirm = "Are you sure you want to change your password? You will need to log back in on all your devices.";
|
out.settings_changePasswordConfirm = "Are you sure you want to change your password? You will need to log back in on all your devices.";
|
||||||
out.settings_changePasswordError = "An unexpected error occurred. If you are unable to login or change your password, contact your CryptPad administrators.";
|
out.settings_changePasswordError = "An unexpected error occurred. If you are unable to login or change your password, contact your CryptPad administrators.";
|
||||||
out.settings_changePasswordPending = "Your password is being updated. Please do not close or reload this page until the process has completed.";
|
out.settings_changePasswordPending = "Your password is being updated. Please do not close or reload this page until the process has completed.";
|
||||||
|
out.settings_changePasswordNewPasswordSameAsOld = "Your new password must be different than your current password.";
|
||||||
|
|
||||||
out.upload_title = "File upload";
|
out.upload_title = "File upload";
|
||||||
out.upload_modal_title = "File upload options";
|
out.upload_modal_title = "File upload options";
|
||||||
@@ -1210,5 +1217,14 @@ define(function () {
|
|||||||
out.loading_drive_2 = "Updating data format";
|
out.loading_drive_2 = "Updating data format";
|
||||||
out.loading_drive_3 = "Verifying data integrity";
|
out.loading_drive_3 = "Verifying data integrity";
|
||||||
|
|
||||||
|
// Shared folders
|
||||||
|
out.sharedFolders_forget = "This pad is only stored in a shared folder, you can't move it to the trash. You can use your CryptDrive if you want to delete it.";
|
||||||
|
out.sharedFolders_duplicate = "Some of the pads you were trying to move were already shared in the destination folder.";
|
||||||
|
out.sharedFolders_create = "Create a shared folder";
|
||||||
|
out.sharedFolders_create_name = "Folder name";
|
||||||
|
out.sharedFolders_create_owned = "Owned folder";
|
||||||
|
out.sharedFolders_create_password = "Folder password";
|
||||||
|
out.sharedFolders_share = "Share this URL with other registered users to give them access to the shared folder. Once they open this URL, the shared folder will be added to the root directory of their CryptDrive.";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "cryptpad",
|
"name": "cryptpad",
|
||||||
"description": "realtime collaborative visual editor with zero knowlege server",
|
"description": "realtime collaborative visual editor with zero knowlege server",
|
||||||
"version": "2.5.0",
|
"version": "2.6.0",
|
||||||
"license": "AGPL-3.0+",
|
"license": "AGPL-3.0+",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chainpad-server": "~2.1.0",
|
"chainpad-server": "~2.1.0",
|
||||||
"express": "~4.16.0",
|
"express": "~4.16.0",
|
||||||
"mkdirp": "^0.5.1",
|
"fs-extra": "^7.0.0",
|
||||||
"nthen": "~0.1.0",
|
"nthen": "~0.1.0",
|
||||||
"pull-stream": "^3.6.1",
|
"pull-stream": "^3.6.1",
|
||||||
"replify": "^1.2.0",
|
"replify": "^1.2.0",
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ As such, it is possible for a collaborator on the pad to include some silly/ugly
|
|||||||
in a CryptPad such as an image which reveals your IP address when your browser automatically
|
in a CryptPad such as an image which reveals your IP address when your browser automatically
|
||||||
loads it or a script which plays Rick Astleys's greatest hits. It is possible for anyone
|
loads it or a script which plays Rick Astleys's greatest hits. It is possible for anyone
|
||||||
who does not have the key to be able to change anything in the pad or add anything, even the
|
who does not have the key to be able to change anything in the pad or add anything, even the
|
||||||
server, however the clients will notice this because the content hashes in ChainPad will fail to
|
server, however the clients will notice this because the content hashes in CryptPad will fail to
|
||||||
validate.
|
validate.
|
||||||
|
|
||||||
The server does have a certain power, it can send you evil javascript which does the wrong
|
The server does have a certain power, it can send you evil javascript which does the wrong
|
||||||
@@ -82,4 +82,4 @@ any later version. If you wish to use this technology in a proprietary product,
|
|||||||
sales@xwiki.com.
|
sales@xwiki.com.
|
||||||
|
|
||||||
[ChainPad]: https://github.com/xwiki-contrib/chainpad
|
[ChainPad]: https://github.com/xwiki-contrib/chainpad
|
||||||
[active attack]: https://en.wikipedia.org/wiki/Attack_(computing)#Types_of_attacks
|
[active attack]: https://en.wikipedia.org/wiki/Attack_(computing)#Types_of_attack
|
||||||
|
|||||||
15
rpc.js
15
rpc.js
@@ -7,13 +7,14 @@ var Nacl = require("tweetnacl");
|
|||||||
/* globals process */
|
/* globals process */
|
||||||
|
|
||||||
var Fs = require("fs");
|
var Fs = require("fs");
|
||||||
|
|
||||||
|
var Fse = require("fs-extra");
|
||||||
var Path = require("path");
|
var Path = require("path");
|
||||||
var Https = require("https");
|
var Https = require("https");
|
||||||
const Package = require('./package.json');
|
const Package = require('./package.json');
|
||||||
const Pinned = require('./pinned');
|
const Pinned = require('./pinned');
|
||||||
const Saferphore = require("saferphore");
|
const Saferphore = require("saferphore");
|
||||||
const nThen = require("nthen");
|
const nThen = require("nthen");
|
||||||
const Mkdirp = require("mkdirp");
|
|
||||||
|
|
||||||
var RPC = module.exports;
|
var RPC = module.exports;
|
||||||
|
|
||||||
@@ -1054,7 +1055,7 @@ var upload_complete = function (Env, publicKey, id, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lol wut handle ur errors
|
// lol wut handle ur errors
|
||||||
Fs.rename(oldPath, newPath, function (e) {
|
Fse.move(oldPath, newPath, function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
WARN('rename', e);
|
WARN('rename', e);
|
||||||
return void cb('RENAME_ERR');
|
return void cb('RENAME_ERR');
|
||||||
@@ -1146,7 +1147,7 @@ var owned_upload_complete = function (Env, safeKey, cb) {
|
|||||||
|
|
||||||
// flow is dumb and I need to guard against this which will never happen
|
// flow is dumb and I need to guard against this which will never happen
|
||||||
// / *:: if (typeof(oldPath) === 'object') { throw new Error('should never happen'); } * /
|
// / *:: if (typeof(oldPath) === 'object') { throw new Error('should never happen'); } * /
|
||||||
Fs.rename(oldPath, finalPath, w(function (e) {
|
Fs.move(oldPath, finalPath, w(function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
w.abort();
|
w.abort();
|
||||||
return void cb(e.code);
|
return void cb(e.code);
|
||||||
@@ -1218,13 +1219,13 @@ var owned_upload_complete = function (Env, safeKey, id, cb) {
|
|||||||
var finalOwnPath;
|
var finalOwnPath;
|
||||||
nThen(function (w) {
|
nThen(function (w) {
|
||||||
// make the requisite directory structure using Mkdirp
|
// make the requisite directory structure using Mkdirp
|
||||||
Mkdirp(filePath, w(function (e /*, path */) {
|
Fse.mkdirp(filePath, w(function (e /*, path */) {
|
||||||
if (e) { // does not throw error if the directory already existed
|
if (e) { // does not throw error if the directory already existed
|
||||||
w.abort();
|
w.abort();
|
||||||
return void cb(e.code);
|
return void cb(e.code);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
Mkdirp(ownPath, w(function (e /*, path */) {
|
Fse.mkdirp(ownPath, w(function (e /*, path */) {
|
||||||
if (e) { // does not throw error if the directory already existed
|
if (e) { // does not throw error if the directory already existed
|
||||||
w.abort();
|
w.abort();
|
||||||
return void cb(e.code);
|
return void cb(e.code);
|
||||||
@@ -1254,7 +1255,7 @@ var owned_upload_complete = function (Env, safeKey, id, cb) {
|
|||||||
|
|
||||||
// flow is dumb and I need to guard against this which will never happen
|
// flow is dumb and I need to guard against this which will never happen
|
||||||
/*:: if (typeof(oldPath) === 'object') { throw new Error('should never happen'); } */
|
/*:: if (typeof(oldPath) === 'object') { throw new Error('should never happen'); } */
|
||||||
Fs.rename(oldPath, finalPath, w(function (e) {
|
Fse.move(oldPath, finalPath, w(function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
// Remove the ownership file
|
// Remove the ownership file
|
||||||
Fs.unlink(finalOwnPath, function (e) {
|
Fs.unlink(finalOwnPath, function (e) {
|
||||||
@@ -1398,7 +1399,7 @@ var writeLoginBlock = function (Env, msg, cb) {
|
|||||||
|
|
||||||
nThen(function (w) {
|
nThen(function (w) {
|
||||||
// make sure the path to the file exists
|
// make sure the path to the file exists
|
||||||
Mkdirp(parsed.dir, w(function (e) {
|
Fse.mkdirp(parsed.dir, w(function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
w.abort();
|
w.abort();
|
||||||
cb(e);
|
cb(e);
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
@import (once) "../../customize/src/less2/include/browser.less";
|
@import (reference) "../../customize/src/less2/include/browser.less";
|
||||||
@import (once) "../../customize/src/less2/include/markdown.less";
|
@import (reference) "../../customize/src/less2/include/markdown.less";
|
||||||
@import (once) "../../customize/src/less2/include/framework.less";
|
@import (reference) "../../customize/src/less2/include/framework.less";
|
||||||
|
|
||||||
|
|
||||||
.framework_main(
|
|
||||||
@bg-color: @colortheme_code-bg,
|
|
||||||
@warn-color: @colortheme_code-warn,
|
|
||||||
@color: @colortheme_code-color
|
|
||||||
);
|
|
||||||
|
|
||||||
// body
|
|
||||||
&.cp-app-code {
|
&.cp-app-code {
|
||||||
|
.framework_main(
|
||||||
|
@bg-color: @colortheme_code-bg,
|
||||||
|
@warn-color: @colortheme_code-warn,
|
||||||
|
@color: @colortheme_code-color
|
||||||
|
);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ define([
|
|||||||
'cm/addon/fold/comment-fold',
|
'cm/addon/fold/comment-fold',
|
||||||
'cm/addon/display/placeholder',
|
'cm/addon/display/placeholder',
|
||||||
|
|
||||||
|
'less!/code/app-code.less'
|
||||||
|
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
DiffMd,
|
DiffMd,
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ const define = (x:any, y:any) => {};
|
|||||||
const require = define;
|
const require = define;
|
||||||
*/
|
*/
|
||||||
define([
|
define([
|
||||||
'/api/config'
|
'/api/config',
|
||||||
], function (Config) { /*::});module.exports = (function() {
|
'/bower_components/nthen/index.js'
|
||||||
|
], function (Config, nThen) { /*::});module.exports = (function() {
|
||||||
const Config = (undefined:any);
|
const Config = (undefined:any);
|
||||||
|
const nThen = (undefined:any);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var module = { exports: {} };
|
var module = { exports: {} };
|
||||||
@@ -100,6 +102,10 @@ define([
|
|||||||
require(['/bower_components/less/dist/less.min.js'], function (Less) {
|
require(['/bower_components/less/dist/less.min.js'], function (Less) {
|
||||||
if (lessEngine) { return void cb(lessEngine); }
|
if (lessEngine) { return void cb(lessEngine); }
|
||||||
lessEngine = Less;
|
lessEngine = Less;
|
||||||
|
Less.functions.functionRegistry.add('LessLoader_currentFile', function () {
|
||||||
|
return new Less.tree.UnicodeDescriptor('"' +
|
||||||
|
fixURL(this.currentFileInfo.filename) + '"');
|
||||||
|
});
|
||||||
var doXHR = lessEngine.FileManager.prototype.doXHR;
|
var doXHR = lessEngine.FileManager.prototype.doXHR;
|
||||||
lessEngine.FileManager.prototype.doXHR = function (url, type, callback, errback) {
|
lessEngine.FileManager.prototype.doXHR = function (url, type, callback, errback) {
|
||||||
url = fixURL(url);
|
url = fixURL(url);
|
||||||
@@ -133,24 +139,38 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.load = function (url /*:string*/, cb /*:()=>void*/) {
|
var loadSubmodulesAndInject = function (css, url, cb, stack) {
|
||||||
var btime = +new Date();
|
inject(css, url);
|
||||||
|
nThen(function (w) {
|
||||||
|
css.replace(/\-\-LessLoader_require\:\s*"([^"]*)"\s*;/g, function (all, u) {
|
||||||
|
u = u.replace(/\?.*$/, '');
|
||||||
|
module.exports.load(u, w(), stack);
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
}).nThen(function () { cb(); });
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.load = function (url /*:string*/, cb /*:()=>void*/, stack /*:?Array<string>*/) {
|
||||||
|
var btime = stack ? null : +new Date();
|
||||||
|
stack = stack || [];
|
||||||
|
if (stack.indexOf(url) > -1) { return void cb(); }
|
||||||
|
var timeout = setTimeout(function () { console.log('failed', url); }, 10000);
|
||||||
var done = function () {
|
var done = function () {
|
||||||
console.log("Compiling [" + url + "] took " + (+new Date() - btime) + "ms");
|
clearTimeout(timeout);
|
||||||
|
if (btime) {
|
||||||
|
console.log("Compiling [" + url + "] took " + (+new Date() - btime) + "ms");
|
||||||
|
}
|
||||||
cb();
|
cb();
|
||||||
};
|
};
|
||||||
|
stack.push(url);
|
||||||
cacheGet(url, function (css) {
|
cacheGet(url, function (css) {
|
||||||
if (css) {
|
if (css) { return void loadSubmodulesAndInject(css, url, done, stack); }
|
||||||
inject(css, url);
|
|
||||||
return void done();
|
|
||||||
}
|
|
||||||
console.log('CACHE MISS ' + url);
|
console.log('CACHE MISS ' + url);
|
||||||
((/\.less([\?\#].*)?$/.test(url)) ? loadLess : loadCSS)(url, function (err, css) {
|
((/\.less([\?\#].*)?$/.test(url)) ? loadLess : loadCSS)(url, function (err, css) {
|
||||||
if (!css) { return void console.error(err); }
|
if (!css) { return void console.error(err); }
|
||||||
var output = fixAllURLs(css, url);
|
var output = fixAllURLs(css, url);
|
||||||
cachePut(url, output);
|
cachePut(url, output);
|
||||||
inject(output, url);
|
loadSubmodulesAndInject(output, url, done, stack);
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -126,5 +126,11 @@ define(function() {
|
|||||||
// Warning: This is an experimental feature. It will be enabled by default once we're sure it's stable.
|
// Warning: This is an experimental feature. It will be enabled by default once we're sure it's stable.
|
||||||
config.disableWorkers = true;
|
config.disableWorkers = true;
|
||||||
|
|
||||||
|
// Shared folder are in a beta-test state. They are likely to disappear from a user's drive
|
||||||
|
// spontaneously, resulting in the deletion of the entire folder's content.
|
||||||
|
// We highly recommend to keep them disabled until they are stable enough to be enabled
|
||||||
|
// by default by the CryptPad developers.
|
||||||
|
config.disableSharedFolders = true;
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -398,10 +398,16 @@ Version 1
|
|||||||
Hash.findWeaker = function (href, channel, recents) {
|
Hash.findWeaker = function (href, channel, recents) {
|
||||||
var parsed = parsePadUrl(href);
|
var parsed = parsePadUrl(href);
|
||||||
if (!parsed.hash) { return false; }
|
if (!parsed.hash) { return false; }
|
||||||
|
// We can't have a weaker hash if we're already in view mode
|
||||||
|
if (parsed.hashData && parsed.hashData.mode === 'view') { return; }
|
||||||
var weaker;
|
var weaker;
|
||||||
Object.keys(recents).some(function (id) {
|
Object.keys(recents).some(function (id) {
|
||||||
var pad = recents[id];
|
var pad = recents[id];
|
||||||
var p = parsePadUrl(pad.href);
|
if (pad.href || !pad.roHref) {
|
||||||
|
// This pad has an edit link, so it can't be weaker
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var p = parsePadUrl(pad.roHref);
|
||||||
if (p.type !== parsed.type) { return; } // Not the same type
|
if (p.type !== parsed.type) { return; } // Not the same type
|
||||||
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
||||||
if (channel !== pad.channel) { return; } // Not the same channel
|
if (channel !== pad.channel) { return; } // Not the same channel
|
||||||
@@ -430,6 +436,10 @@ Version 1
|
|||||||
var stronger;
|
var stronger;
|
||||||
Object.keys(recents).some(function (id) {
|
Object.keys(recents).some(function (id) {
|
||||||
var pad = recents[id];
|
var pad = recents[id];
|
||||||
|
if (!pad.href) {
|
||||||
|
// This pad doesn't have an edit link, so it can't be stronger
|
||||||
|
return;
|
||||||
|
}
|
||||||
var p = parsePadUrl(pad.href);
|
var p = parsePadUrl(pad.href);
|
||||||
if (p.type !== parsed.type) { return; } // Not the same type
|
if (p.type !== parsed.type) { return; } // Not the same type
|
||||||
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
|
if (!document.querySelector("#alertifyCSS")) {
|
||||||
|
// Prevent alertify from injecting CSS, we create our own in alertify.less.
|
||||||
|
// see: https://github.com/alertifyjs/alertify.js/blob/v1.0.11/src/js/alertify.js#L414
|
||||||
|
var head = document.getElementsByTagName("head")[0];
|
||||||
|
var css = document.createElement("span");
|
||||||
|
css.id = "alertifyCSS";
|
||||||
|
css.setAttribute('data-but-why', 'see: common-interface.js');
|
||||||
|
head.insertBefore(css, head.firstChild);
|
||||||
|
}
|
||||||
define([
|
define([
|
||||||
'jquery',
|
'jquery',
|
||||||
'/customize/messages.js',
|
'/customize/messages.js',
|
||||||
@@ -665,7 +674,7 @@ define([
|
|||||||
// Update the current state
|
// Update the current state
|
||||||
loading.driveState = data.state;
|
loading.driveState = data.state;
|
||||||
data.progress = data.progress || 100;
|
data.progress = data.progress || 100;
|
||||||
data.msg = Messages['loading_drive_'+data.state] || '';
|
data.msg = Messages['loading_drive_'+ Math.floor(data.state)] || '';
|
||||||
$progress.html(data.msg);
|
$progress.html(data.msg);
|
||||||
if (data.progress) {
|
if (data.progress) {
|
||||||
$progress.append(h('div.cp-loading-progress-bar', [
|
$progress.append(h('div.cp-loading-progress-bar', [
|
||||||
@@ -761,7 +770,7 @@ define([
|
|||||||
UI.getFileIcon = function (data) {
|
UI.getFileIcon = function (data) {
|
||||||
var $icon = UI.getIcon();
|
var $icon = UI.getIcon();
|
||||||
if (!data) { return $icon; }
|
if (!data) { return $icon; }
|
||||||
var href = data.href;
|
var href = data.href || data.roHref;
|
||||||
var type = data.type;
|
var type = data.type;
|
||||||
if (!href && !type) { return $icon; }
|
if (!href && !type) { return $icon; }
|
||||||
|
|
||||||
@@ -826,13 +835,13 @@ define([
|
|||||||
var out = false;
|
var out = false;
|
||||||
var xId = $(x).attr('aria-describedby');
|
var xId = $(x).attr('aria-describedby');
|
||||||
if (xId) {
|
if (xId) {
|
||||||
if (xId.indexOf('tippy-tooltip-') === 0) {
|
if (xId.indexOf('tippy-') === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(x).find('[aria-describedby]').each(function (i, el) {
|
$(x).find('[aria-describedby]').each(function (i, el) {
|
||||||
var id = el.getAttribute('aria-describedby');
|
var id = el.getAttribute('aria-describedby');
|
||||||
if (id.indexOf('tippy-tooltip-') !== 0) { return; }
|
if (id.indexOf('tippy-') !== 0) { return; }
|
||||||
out = true;
|
out = true;
|
||||||
});
|
});
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ define([
|
|||||||
'/customize/messages.js',
|
'/customize/messages.js',
|
||||||
'/customize/application_config.js',
|
'/customize/application_config.js',
|
||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
|
'css!/customize/fonts/cptools/style.css'
|
||||||
], function ($, Config, Util, Hash, Language, UI, Constants, Feedback, h, MediaTag, Clipboard,
|
], function ($, Config, Util, Hash, Language, UI, Constants, Feedback, h, MediaTag, Clipboard,
|
||||||
Messages, AppConfig, NThen) {
|
Messages, AppConfig, NThen) {
|
||||||
var UIElements = {};
|
var UIElements = {};
|
||||||
@@ -73,26 +74,14 @@ define([
|
|||||||
data.password = val;
|
data.password = val;
|
||||||
}));
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
|
var base = common.getMetadataMgr().getPrivateData().origin;
|
||||||
common.getPadAttribute('href', waitFor(function (err, val) {
|
common.getPadAttribute('href', waitFor(function (err, val) {
|
||||||
var base = common.getMetadataMgr().getPrivateData().origin;
|
if (!val) { return; }
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(val);
|
|
||||||
if (parsed.hashData.mode === "view") {
|
|
||||||
data.roHref = base + val;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're not in a read-only pad
|
|
||||||
data.href = base + val;
|
data.href = base + val;
|
||||||
|
}));
|
||||||
// Get Read-only href
|
common.getPadAttribute('roHref', waitFor(function (err, val) {
|
||||||
if (parsed.hashData.type !== "pad") { return; }
|
if (!val) { return; }
|
||||||
var i = data.href.indexOf('#') + 1;
|
data.roHref = base + val;
|
||||||
var hBase = data.href.slice(0, i);
|
|
||||||
var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
|
|
||||||
if (!hrefsecret.keys) { return; }
|
|
||||||
var viewHash = Hash.getViewHashFromKeys(hrefsecret);
|
|
||||||
data.roHref = hBase + viewHash;
|
|
||||||
}));
|
}));
|
||||||
common.getPadAttribute('channel', waitFor(function (err, val) {
|
common.getPadAttribute('channel', waitFor(function (err, val) {
|
||||||
data.channel = val;
|
data.channel = val;
|
||||||
@@ -137,82 +126,86 @@ define([
|
|||||||
id: 'cp-app-prop-owners',
|
id: 'cp-app-prop-owners',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var expire = Messages.creation_expireFalse;
|
if (!data.noExpiration) {
|
||||||
if (data.expire && typeof (data.expire) === "number") {
|
var expire = Messages.creation_expireFalse;
|
||||||
expire = new Date(data.expire).toLocaleString();
|
if (data.expire && typeof (data.expire) === "number") {
|
||||||
}
|
expire = new Date(data.expire).toLocaleString();
|
||||||
$('<label>', {'for': 'cp-app-prop-expire'}).text(Messages.creation_expiration)
|
|
||||||
.appendTo($d);
|
|
||||||
$d.append(UI.dialog.selectable(expire, {
|
|
||||||
id: 'cp-app-prop-expire',
|
|
||||||
}));
|
|
||||||
|
|
||||||
var hasPassword = data.password;
|
|
||||||
if (hasPassword) {
|
|
||||||
$('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue)
|
|
||||||
.appendTo($d);
|
|
||||||
var password = UI.passwordInput({
|
|
||||||
id: 'cp-app-prop-password',
|
|
||||||
readonly: 'readonly'
|
|
||||||
});
|
|
||||||
var $pwInput = $(password).find('.cp-password-input');
|
|
||||||
$pwInput.val(data.password).click(function () {
|
|
||||||
$pwInput[0].select();
|
|
||||||
});
|
|
||||||
$d.append(password);
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(data.href);
|
|
||||||
if (owned && parsed.hashData.type === 'pad') {
|
|
||||||
var sframeChan = common.getSframeChannel();
|
|
||||||
var changePwTitle = Messages.properties_changePassword;
|
|
||||||
var changePwConfirm = Messages.properties_confirmChange;
|
|
||||||
if (!hasPassword) {
|
|
||||||
changePwTitle = Messages.properties_addPassword;
|
|
||||||
changePwConfirm = Messages.properties_confirmNew;
|
|
||||||
}
|
}
|
||||||
$('<label>', {'for': 'cp-app-prop-change-password'})
|
$('<label>', {'for': 'cp-app-prop-expire'}).text(Messages.creation_expiration)
|
||||||
.text(changePwTitle).appendTo($d);
|
.appendTo($d);
|
||||||
var newPassword = UI.passwordInput({
|
$d.append(UI.dialog.selectable(expire, {
|
||||||
id: 'cp-app-prop-change-password',
|
id: 'cp-app-prop-expire',
|
||||||
style: 'flex: 1;'
|
}));
|
||||||
});
|
}
|
||||||
var passwordOk = h('button', Messages.properties_changePasswordButton);
|
|
||||||
var changePass = h('span.cp-password-container', [
|
if (!data.noPassword) {
|
||||||
newPassword,
|
var hasPassword = data.password;
|
||||||
passwordOk
|
if (hasPassword) {
|
||||||
]);
|
$('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue)
|
||||||
$(passwordOk).click(function () {
|
.appendTo($d);
|
||||||
var newPass = $(newPassword).find('input').val();
|
var password = UI.passwordInput({
|
||||||
if (data.password === newPass ||
|
id: 'cp-app-prop-password',
|
||||||
(!data.password && !newPass)) {
|
readonly: 'readonly'
|
||||||
return void UI.alert(Messages.properties_passwordSame);
|
});
|
||||||
|
var $pwInput = $(password).find('.cp-password-input');
|
||||||
|
$pwInput.val(data.password).click(function () {
|
||||||
|
$pwInput[0].select();
|
||||||
|
});
|
||||||
|
$d.append(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||||
|
if (owned && parsed.hashData.type === 'pad') {
|
||||||
|
var sframeChan = common.getSframeChannel();
|
||||||
|
var changePwTitle = Messages.properties_changePassword;
|
||||||
|
var changePwConfirm = Messages.properties_confirmChange;
|
||||||
|
if (!hasPassword) {
|
||||||
|
changePwTitle = Messages.properties_addPassword;
|
||||||
|
changePwConfirm = Messages.properties_confirmNew;
|
||||||
}
|
}
|
||||||
UI.confirm(changePwConfirm, function (yes) {
|
$('<label>', {'for': 'cp-app-prop-change-password'})
|
||||||
if (!yes) { return; }
|
.text(changePwTitle).appendTo($d);
|
||||||
sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
|
var newPassword = UI.passwordInput({
|
||||||
href: data.href,
|
id: 'cp-app-prop-change-password',
|
||||||
password: newPass
|
style: 'flex: 1;'
|
||||||
}, function (err, data) {
|
});
|
||||||
if (err || data.error) {
|
var passwordOk = h('button', Messages.properties_changePasswordButton);
|
||||||
return void UI.alert(Messages.properties_passwordError);
|
var changePass = h('span.cp-password-container', [
|
||||||
}
|
newPassword,
|
||||||
UI.findOKButton().click();
|
passwordOk
|
||||||
// If we didn't have a password, we have to add the /p/
|
]);
|
||||||
// If we had a password and we changed it to a new one, we just have to reload
|
$(passwordOk).click(function () {
|
||||||
// If we had a password and we removed it, we have to remove the /p/
|
var newPass = $(newPassword).find('input').val();
|
||||||
if (data.warning) {
|
if (data.password === newPass ||
|
||||||
return void UI.alert(Messages.properties_passwordWarning, function () {
|
(!data.password && !newPass)) {
|
||||||
common.gotoURL(hasPassword && newPass ? undefined : data.href);
|
return void UI.alert(Messages.properties_passwordSame);
|
||||||
}, {force: true});
|
}
|
||||||
}
|
UI.confirm(changePwConfirm, function (yes) {
|
||||||
return void UI.alert(Messages.properties_passwordSuccess, function () {
|
if (!yes) { return; }
|
||||||
common.gotoURL(hasPassword && newPass ? undefined : data.href);
|
sframeChan.query("Q_PAD_PASSWORD_CHANGE", {
|
||||||
}, {force: true});
|
href: data.href || data.roHref,
|
||||||
|
password: newPass
|
||||||
|
}, function (err, data) {
|
||||||
|
if (err || data.error) {
|
||||||
|
return void UI.alert(Messages.properties_passwordError);
|
||||||
|
}
|
||||||
|
UI.findOKButton().click();
|
||||||
|
// If we didn't have a password, we have to add the /p/
|
||||||
|
// If we had a password and we changed it to a new one, we just have to reload
|
||||||
|
// If we had a password and we removed it, we have to remove the /p/
|
||||||
|
if (data.warning) {
|
||||||
|
return void UI.alert(Messages.properties_passwordWarning, function () {
|
||||||
|
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
||||||
|
}, {force: true});
|
||||||
|
}
|
||||||
|
return void UI.alert(Messages.properties_passwordSuccess, function () {
|
||||||
|
common.gotoURL(hasPassword && newPass ? undefined : (data.href || data.roHref));
|
||||||
|
}, {force: true});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
$d.append(changePass);
|
||||||
$d.append(changePass);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cb(void 0, $d);
|
cb(void 0, $d);
|
||||||
@@ -242,17 +235,21 @@ define([
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
$('<label>', {'for': 'cp-app-prop-ctime'}).text(Messages.fm_creation)
|
if (data.ctime) {
|
||||||
.appendTo($d);
|
$('<label>', {'for': 'cp-app-prop-ctime'}).text(Messages.fm_creation)
|
||||||
$d.append(UI.dialog.selectable(new Date(data.ctime).toLocaleString(), {
|
.appendTo($d);
|
||||||
id: 'cp-app-prop-ctime',
|
$d.append(UI.dialog.selectable(new Date(data.ctime).toLocaleString(), {
|
||||||
}));
|
id: 'cp-app-prop-ctime',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
$('<label>', {'for': 'cp-app-prop-atime'}).text(Messages.fm_lastAccess)
|
if (data.atime) {
|
||||||
.appendTo($d);
|
$('<label>', {'for': 'cp-app-prop-atime'}).text(Messages.fm_lastAccess)
|
||||||
$d.append(UI.dialog.selectable(new Date(data.atime).toLocaleString(), {
|
.appendTo($d);
|
||||||
id: 'cp-app-prop-atime',
|
$d.append(UI.dialog.selectable(new Date(data.atime).toLocaleString(), {
|
||||||
}));
|
id: 'cp-app-prop-atime',
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if (common.isLoggedIn() && AppConfig.enablePinning) {
|
if (common.isLoggedIn() && AppConfig.enablePinning) {
|
||||||
// check the size of this file...
|
// check the size of this file...
|
||||||
@@ -463,6 +460,7 @@ define([
|
|||||||
var pathname = config.pathname;
|
var pathname = config.pathname;
|
||||||
var hashes = config.hashes;
|
var hashes = config.hashes;
|
||||||
var common = config.common;
|
var common = config.common;
|
||||||
|
var fileData = config.fileData;
|
||||||
|
|
||||||
if (!hashes.fileHash) { throw new Error("You must provide a file hash"); }
|
if (!hashes.fileHash) { throw new Error("You must provide a file hash"); }
|
||||||
var url = origin + pathname + '#' + hashes.fileHash;
|
var url = origin + pathname + '#' + hashes.fileHash;
|
||||||
@@ -498,7 +496,7 @@ define([
|
|||||||
UI.dialog.selectable(common.getMediatagScript()),
|
UI.dialog.selectable(common.getMediatagScript()),
|
||||||
h('p', Messages.fileEmbedTag),
|
h('p', Messages.fileEmbedTag),
|
||||||
h('br'),
|
h('br'),
|
||||||
UI.dialog.selectable(common.getMediatagFromHref(url)),
|
UI.dialog.selectable(common.getMediatagFromHref(fileData)),
|
||||||
]);
|
]);
|
||||||
var embedButtons = [{
|
var embedButtons = [{
|
||||||
name: Messages.cancel,
|
name: Messages.cancel,
|
||||||
@@ -508,7 +506,7 @@ define([
|
|||||||
className: 'primary',
|
className: 'primary',
|
||||||
name: Messages.share_mediatagCopy,
|
name: Messages.share_mediatagCopy,
|
||||||
onClick: function () {
|
onClick: function () {
|
||||||
var v = common.getMediatagFromHref(url);
|
var v = common.getMediatagFromHref(fileData);
|
||||||
var success = Clipboard.copy(v);
|
var success = Clipboard.copy(v);
|
||||||
if (success) { UI.log(Messages.shareSuccess); }
|
if (success) { UI.log(Messages.shareSuccess); }
|
||||||
},
|
},
|
||||||
@@ -533,6 +531,35 @@ define([
|
|||||||
}
|
}
|
||||||
return tabs;
|
return tabs;
|
||||||
};
|
};
|
||||||
|
UIElements.createSFShareModal = function (config) {
|
||||||
|
var origin = config.origin;
|
||||||
|
var pathname = config.pathname;
|
||||||
|
var hashes = config.hashes;
|
||||||
|
|
||||||
|
if (!hashes.editHash) { throw new Error("You must provide a valid hash"); }
|
||||||
|
var url = origin + pathname + '#' + hashes.editHash;
|
||||||
|
|
||||||
|
// Share link tab
|
||||||
|
var link = h('div.cp-share-modal', [
|
||||||
|
h('label', Messages.sharedFolders_share),
|
||||||
|
h('br'),
|
||||||
|
UI.dialog.selectable(url, { id: 'cp-share-link-preview', tabindex: 1 })
|
||||||
|
]);
|
||||||
|
var linkButtons = [{
|
||||||
|
name: Messages.cancel,
|
||||||
|
onClick: function () {},
|
||||||
|
keys: [27]
|
||||||
|
}, {
|
||||||
|
className: 'primary',
|
||||||
|
name: Messages.share_linkCopy,
|
||||||
|
onClick: function () {
|
||||||
|
var success = Clipboard.copy(url);
|
||||||
|
if (success) { UI.log(Messages.shareSuccess); }
|
||||||
|
},
|
||||||
|
keys: [13]
|
||||||
|
}];
|
||||||
|
return UI.dialog.customModal(link, {buttons: linkButtons});
|
||||||
|
};
|
||||||
|
|
||||||
UIElements.createButton = function (common, type, rightside, data, callback) {
|
UIElements.createButton = function (common, type, rightside, data, callback) {
|
||||||
var AppConfig = common.getAppConfig();
|
var AppConfig = common.getAppConfig();
|
||||||
@@ -695,17 +722,27 @@ define([
|
|||||||
button
|
button
|
||||||
.click(common.prepareFeedback(type))
|
.click(common.prepareFeedback(type))
|
||||||
.click(function() {
|
.click(function() {
|
||||||
var msg = common.isLoggedIn() ? Messages.forgetPrompt : Messages.fm_removePermanentlyDialog;
|
sframeChan.query('Q_IS_ONLY_IN_SHARED_FOLDER', null, function (err, res) {
|
||||||
UI.confirm(msg, function (yes) {
|
if (err || res.error) { return void console.log(err || res.error); }
|
||||||
if (!yes) { return; }
|
var msg = Messages.forgetPrompt;
|
||||||
sframeChan.query('Q_MOVE_TO_TRASH', null, function (err) {
|
if (res) {
|
||||||
if (err) { return void callback(err); }
|
UI.alert(Messages.sharedFolders_forget);
|
||||||
var cMsg = common.isLoggedIn() ? Messages.movedToTrash : Messages.deleted;
|
|
||||||
var msg = common.fixLinks($('<div>').html(cMsg));
|
|
||||||
UI.alert(msg);
|
|
||||||
callback();
|
|
||||||
return;
|
return;
|
||||||
|
} else if (!common.isLoggedIn()) {
|
||||||
|
msg = Messages.fm_removePermanentlyDialog;
|
||||||
|
}
|
||||||
|
UI.confirm(msg, function (yes) {
|
||||||
|
if (!yes) { return; }
|
||||||
|
sframeChan.query('Q_MOVE_TO_TRASH', null, function (err) {
|
||||||
|
if (err) { return void callback(err); }
|
||||||
|
var cMsg = common.isLoggedIn() ? Messages.movedToTrash : Messages.deleted;
|
||||||
|
var msg = common.fixLinks($('<div>').html(cMsg));
|
||||||
|
UI.alert(msg);
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -2010,12 +2047,14 @@ define([
|
|||||||
allData.unshift({
|
allData.unshift({
|
||||||
name: Messages.creation_newTemplate,
|
name: Messages.creation_newTemplate,
|
||||||
id: -1,
|
id: -1,
|
||||||
icon: h('span.fa.fa-bookmark')
|
//icon: h('span.fa.fa-bookmark')
|
||||||
|
icon: h('span.cptools.cptools-new-template')
|
||||||
});
|
});
|
||||||
allData.unshift({
|
allData.unshift({
|
||||||
name: Messages.creation_noTemplate,
|
name: Messages.creation_noTemplate,
|
||||||
id: 0,
|
id: 0,
|
||||||
icon: h('span.fa.fa-file')
|
//icon: h('span.fa.fa-file')
|
||||||
|
icon: UI.getFileIcon({type: type})
|
||||||
});
|
});
|
||||||
var redraw = function (index) {
|
var redraw = function (index) {
|
||||||
if (index < 0) { i = 0; }
|
if (index < 0) { i = 0; }
|
||||||
@@ -2031,7 +2070,9 @@ define([
|
|||||||
}).appendTo($container);
|
}).appendTo($container);
|
||||||
$span.data('id', obj.id);
|
$span.data('id', obj.id);
|
||||||
if (idx === selected) { $span.addClass('cp-creation-template-selected'); }
|
if (idx === selected) { $span.addClass('cp-creation-template-selected'); }
|
||||||
$span.append(obj.icon || UI.getFileIcon({type: type}));
|
if (!obj.thumbnail) {
|
||||||
|
$span.append(obj.icon || h('span.cptools.cptools-template'));
|
||||||
|
}
|
||||||
$('<span>', {'class': 'cp-creation-template-element-name'}).text(name)
|
$('<span>', {'class': 'cp-creation-template-element-name'}).text(name)
|
||||||
.appendTo($span);
|
.appendTo($span);
|
||||||
$span.click(function () {
|
$span.click(function () {
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ define([
|
|||||||
cb(obj);
|
cb(obj);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
common.getSharedFolder = function (id, cb) {
|
||||||
|
postMessage("GET_SHARED_FOLDER", id, function (obj) {
|
||||||
|
cb(obj);
|
||||||
|
});
|
||||||
|
};
|
||||||
// Settings and ready
|
// Settings and ready
|
||||||
common.mergeAnonDrive = function (cb) {
|
common.mergeAnonDrive = function (cb) {
|
||||||
var data = {
|
var data = {
|
||||||
@@ -99,6 +104,27 @@ define([
|
|||||||
common.userObjectCommand = function (data, cb) {
|
common.userObjectCommand = function (data, cb) {
|
||||||
postMessage("DRIVE_USEROBJECT", data, cb);
|
postMessage("DRIVE_USEROBJECT", data, cb);
|
||||||
};
|
};
|
||||||
|
common.restoreDrive = function (data, cb) {
|
||||||
|
postMessage("SET", {
|
||||||
|
key:['drive'],
|
||||||
|
value: data
|
||||||
|
}, function (obj) {
|
||||||
|
cb(obj);
|
||||||
|
}, {
|
||||||
|
timeout: 5 * 60 * 1000
|
||||||
|
});
|
||||||
|
};
|
||||||
|
common.addSharedFolder = function (secret, cb) {
|
||||||
|
postMessage("ADD_SHARED_FOLDER", {
|
||||||
|
path: ['root'],
|
||||||
|
folderData: {
|
||||||
|
href: '/drive/#' + Hash.getEditHashFromKeys(secret),
|
||||||
|
roHref: '/drive/#' + Hash.getViewHashFromKeys(secret),
|
||||||
|
channel: secret.channel,
|
||||||
|
ctime: +new Date()
|
||||||
|
}
|
||||||
|
}, cb);
|
||||||
|
};
|
||||||
common.drive = {};
|
common.drive = {};
|
||||||
common.drive.onLog = Util.mkEvent();
|
common.drive.onLog = Util.mkEvent();
|
||||||
common.drive.onChange = Util.mkEvent();
|
common.drive.onChange = Util.mkEvent();
|
||||||
@@ -294,6 +320,13 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
common.isOnlyInSharedFolder = function (data, cb) {
|
||||||
|
postMessage("IS_ONLY_IN_SHARED_FOLDER", data, function (obj) {
|
||||||
|
if (obj && obj.error) { return void cb(obj.error); }
|
||||||
|
cb(null, obj);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
common.setDisplayName = function (value, cb) {
|
common.setDisplayName = function (value, cb) {
|
||||||
postMessage("SET_DISPLAY_NAME", value, cb);
|
postMessage("SET_DISPLAY_NAME", value, cb);
|
||||||
};
|
};
|
||||||
@@ -506,7 +539,8 @@ define([
|
|||||||
|
|
||||||
if (common.initialPath) {
|
if (common.initialPath) {
|
||||||
if (!data.path) {
|
if (!data.path) {
|
||||||
data.path = common.initialPath;
|
data.path = Array.isArray(common.initialPath) ? common.initialPath
|
||||||
|
: decodeURIComponent(common.initialPath).split(',');
|
||||||
delete common.initialPath;
|
delete common.initialPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,7 +654,7 @@ define([
|
|||||||
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
|
if (!parsed.hash) { return void cb({ error: 'EINVAL_HREF' }); }
|
||||||
|
|
||||||
var warning = false;
|
var warning = false;
|
||||||
var newHash;
|
var newHash, newRoHref;
|
||||||
var oldChannel;
|
var oldChannel;
|
||||||
var newSecret;
|
var newSecret;
|
||||||
|
|
||||||
@@ -693,6 +727,11 @@ define([
|
|||||||
common.setPadAttribute('channel', newSecret.channel, waitFor(function (err) {
|
common.setPadAttribute('channel', newSecret.channel, waitFor(function (err) {
|
||||||
if (err) { warning = true; }
|
if (err) { warning = true; }
|
||||||
}), href);
|
}), href);
|
||||||
|
var viewHash = Hash.getViewHashFromKeys(newSecret);
|
||||||
|
newRoHref = '/' + parsed.type + '/#' + viewHash;
|
||||||
|
common.setPadAttribute('roHref', newRoHref, waitFor(function (err) {
|
||||||
|
if (err) { warning = true; }
|
||||||
|
}), href);
|
||||||
|
|
||||||
if (parsed.hashData.password && newPassword) { return; } // same hash
|
if (parsed.hashData.password && newPassword) { return; } // same hash
|
||||||
common.setPadAttribute('href', newHref, waitFor(function (err) {
|
common.setPadAttribute('href', newHref, waitFor(function (err) {
|
||||||
@@ -702,7 +741,8 @@ define([
|
|||||||
cb({
|
cb({
|
||||||
warning: warning,
|
warning: warning,
|
||||||
hash: newHash,
|
hash: newHash,
|
||||||
href: newHref
|
href: newHref,
|
||||||
|
roHref: newRoHref
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1290,12 +1330,12 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
postMessage = function (cmd, data, cb) {
|
postMessage = function (cmd, data, cb, opts) {
|
||||||
cb = cb || function () {};
|
cb = cb || function () {};
|
||||||
chan.query(cmd, data, function (err, data) {
|
chan.query(cmd, data, function (err, data) {
|
||||||
if (err) { return void cb ({error: err}); }
|
if (err) { return void cb ({error: err}); }
|
||||||
cb(data);
|
cb(data);
|
||||||
});
|
}, opts);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('Posting CONNECT');
|
console.log('Posting CONNECT');
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
@import (once) '../customize/src/less2/include/colortheme-all.less';
|
@import (reference) '../customize/src/less2/include/colortheme-all.less';
|
||||||
@import '../customize/src/less2/include/modal.less';
|
@import (reference) '../customize/src/less2/include/modal.less';
|
||||||
|
|
||||||
.fileDialog_main () {
|
.fileDialog_main () {
|
||||||
#fileDialog {
|
#fileDialog {
|
||||||
|
.modal_main();
|
||||||
display: none;
|
display: none;
|
||||||
.cp-modal {
|
.cp-modal {
|
||||||
.fileContainer {
|
.fileContainer {
|
||||||
|
|||||||
@@ -6,84 +6,6 @@ define([
|
|||||||
], function (Crypt, FO, Hash, Realtime) {
|
], function (Crypt, FO, Hash, Realtime) {
|
||||||
var exp = {};
|
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 createFromPath = function (proxy, oldFo, path, id) {
|
|
||||||
var root = proxy.drive;
|
|
||||||
|
|
||||||
if (!oldFo.isFile(id)) { return; }
|
|
||||||
|
|
||||||
var error = function (msg) {
|
|
||||||
console.error(msg || "Unable to find that path", path);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (oldFo.isInTrashRoot(path)) {
|
|
||||||
id = oldFo.find(path.slice(0,3));
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
var 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[Hash.createChannelId()] = id;
|
|
||||||
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(id) === -1) { root.push(id); }
|
|
||||||
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;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
exp.anonDriveIntoUser = function (proxyData, fsHash, cb) {
|
exp.anonDriveIntoUser = function (proxyData, fsHash, cb) {
|
||||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||||
if (!fsHash || !proxyData.loggedIn) {
|
if (!fsHash || !proxyData.loggedIn) {
|
||||||
@@ -105,43 +27,38 @@ define([
|
|||||||
if (parsed) {
|
if (parsed) {
|
||||||
var proxy = proxyData.proxy;
|
var proxy = proxyData.proxy;
|
||||||
var oldFo = FO.init(parsed.drive, {
|
var oldFo = FO.init(parsed.drive, {
|
||||||
loggedIn: proxyData.loggedIn,
|
loggedIn: true,
|
||||||
pinPads: function () {} // without pinPads /outer/userObject.js won't be loaded
|
outer: true
|
||||||
});
|
});
|
||||||
var onMigrated = function () {
|
var onMigrated = function () {
|
||||||
oldFo.fixFiles(true);
|
oldFo.fixFiles(true);
|
||||||
var newFo = proxyData.userObject;
|
var manager = proxyData.manager;
|
||||||
var oldRecentPads = parsed.drive[newFo.FILES_DATA];
|
var oldFiles = oldFo.getFiles([oldFo.FILES_DATA]);
|
||||||
var newRecentPads = proxy.drive[newFo.FILES_DATA];
|
|
||||||
var oldFiles = oldFo.getFiles([newFo.FILES_DATA]);
|
|
||||||
var newHrefs = Object.keys(newRecentPads).map(function (id) {
|
|
||||||
return newRecentPads[id].href;
|
|
||||||
});
|
|
||||||
oldFiles.forEach(function (id) {
|
oldFiles.forEach(function (id) {
|
||||||
var href = oldRecentPads[id].href;
|
var data = oldFo.getFileData(id);
|
||||||
// Do not migrate a pad if we already have it, it would create a duplicate in the drive
|
var channel = data.channel;
|
||||||
if (newHrefs.indexOf(href) !== -1) { return; }
|
|
||||||
// If we have a stronger version, do not add the current href
|
var datas = manager.findChannel(channel, true);
|
||||||
if (Hash.findStronger(href, oldRecentPads[id].channel, newRecentPads)) { return; }
|
// Do not migrate a pad if we already have it, it would create a duplicate
|
||||||
// If we have a weaker version, replace the href by the new one
|
// in the drive
|
||||||
// NOTE: if that weaker version is in the trash, the strong one will be put in unsorted
|
if (datas.length !== 0) {
|
||||||
var weaker = Hash.findWeaker(href, oldRecentPads[id].channel, newRecentPads);
|
// We want to merge a read-only pad: it can't be stronger than what
|
||||||
if (weaker) {
|
// we already have so abort
|
||||||
// Update RECENTPADS
|
if (!data.href) { return; }
|
||||||
weaker.href = href;
|
|
||||||
// Update the file in the drive
|
// We want to merge an edit pad: check if we have the same channel
|
||||||
newFo.replace(weaker.href, href);
|
// but read-only and upgrade it in that case
|
||||||
|
datas.forEach(function (pad) {
|
||||||
|
if (!pad.href) { data.href = pad.href; }
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Here it means we have a new href, so we should add it to the drive at its old location
|
// Here it means we have a new href, so we should add it to the drive
|
||||||
var paths = oldFo.findFile(id);
|
|
||||||
if (paths.length === 0) { return; }
|
|
||||||
// Add the file data in our array and use the id to add the file
|
|
||||||
var data = oldFo.getFileData(id);
|
|
||||||
if (data) {
|
if (data) {
|
||||||
newFo.pushData(data, function (err, id) {
|
manager.addPad(null, data, function (err) {
|
||||||
if (err) { return void console.error("Cannot import file:", data, err); }
|
if (err) {
|
||||||
createFromPath(proxy, oldFo, paths[0], id);
|
return void console.error("Cannot import file:", data, err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -153,7 +70,12 @@ define([
|
|||||||
Realtime.whenRealtimeSyncs(proxyData.realtime, cb);
|
Realtime.whenRealtimeSyncs(proxyData.realtime, cb);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
oldFo.migrate(onMigrated);
|
if (oldFo && typeof(oldFo.migrate) === 'function') {
|
||||||
|
oldFo.migrate(onMigrated);
|
||||||
|
} else {
|
||||||
|
console.log('oldFo.migrate is not a function');
|
||||||
|
onMigrated();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (typeof(cb) === "function") { cb(); }
|
if (typeof(cb) === "function") { cb(); }
|
||||||
|
|||||||
@@ -123,12 +123,58 @@ define([
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
n.nThen(waitFor());
|
n.nThen(waitFor(function () {
|
||||||
|
Feedback.send('Migrate-6', true);
|
||||||
|
userObject.version = version = 6;
|
||||||
|
}));
|
||||||
};
|
};
|
||||||
if (version < 6) {
|
if (version < 6) {
|
||||||
addChannelId();
|
addChannelId();
|
||||||
Feedback.send('Migrate-6', true);
|
}
|
||||||
userObject.version = version = 6;
|
}).nThen(function (waitFor) {
|
||||||
|
var addRoHref = function () {
|
||||||
|
var data = userObject.drive.filesData;
|
||||||
|
var el, parsed;
|
||||||
|
var n = nThen(function () {});
|
||||||
|
var padsLength = Object.keys(data).length;
|
||||||
|
Object.keys(data).forEach(function (k, i) {
|
||||||
|
n = n.nThen(function (w) {
|
||||||
|
setTimeout(w(function () {
|
||||||
|
el = data[k];
|
||||||
|
if (!el.href || (el.roHref && false)) {
|
||||||
|
// Already migrated
|
||||||
|
return void progress(7, Math.round(100*i/padsLength));
|
||||||
|
}
|
||||||
|
parsed = Hash.parsePadUrl(el.href);
|
||||||
|
if (parsed.hashData.type !== "pad") {
|
||||||
|
// No read-only mode for files
|
||||||
|
return void progress(7, Math.round(100*i/padsLength));
|
||||||
|
}
|
||||||
|
if (parsed.hashData.mode === "view") {
|
||||||
|
// This is a read-only pad in our drive
|
||||||
|
el.roHref = el.href;
|
||||||
|
delete el.href;
|
||||||
|
console.log('Move href to roHref in filesData ', el.roHref);
|
||||||
|
} else {
|
||||||
|
var secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
||||||
|
var hash = Hash.getViewHashFromKeys(secret);
|
||||||
|
if (hash) {
|
||||||
|
// Version 0 won't have a view hash available
|
||||||
|
el.roHref = '/' + parsed.type + '/#' + hash;
|
||||||
|
console.log('Adding missing roHref in filesData ', el.href);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
progress(6, Math.round(100*i/padsLength));
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
n.nThen(waitFor(function () {
|
||||||
|
Feedback.send('Migrate-7', true);
|
||||||
|
userObject.version = version = 7;
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
if (version < 7) {
|
||||||
|
addRoHref();
|
||||||
}
|
}
|
||||||
/*}).nThen(function (waitFor) {
|
/*}).nThen(function (waitFor) {
|
||||||
// Test progress bar in the loading screen
|
// Test progress bar in the loading screen
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
define([
|
define([
|
||||||
'json.sortify',
|
'json.sortify',
|
||||||
'/common/userObject.js',
|
'/common/userObject.js',
|
||||||
|
'/common/proxy-manager.js',
|
||||||
'/common/migrate-user-object.js',
|
'/common/migrate-user-object.js',
|
||||||
'/common/common-hash.js',
|
'/common/common-hash.js',
|
||||||
'/common/common-util.js',
|
'/common/common-util.js',
|
||||||
@@ -18,7 +19,7 @@ define([
|
|||||||
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||||
'/bower_components/nthen/index.js',
|
'/bower_components/nthen/index.js',
|
||||||
'/bower_components/saferphore/index.js',
|
'/bower_components/saferphore/index.js',
|
||||||
], function (Sortify, UserObject, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Messenger,
|
], function (Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Messenger,
|
||||||
CpNfWorker, NetConfig, AppConfig,
|
CpNfWorker, NetConfig, AppConfig,
|
||||||
Crypto, ChainPad, Listmap, nThen, Saferphore) {
|
Crypto, ChainPad, Listmap, nThen, Saferphore) {
|
||||||
var Store = {};
|
var Store = {};
|
||||||
@@ -27,17 +28,23 @@ define([
|
|||||||
var postMessage = function () {};
|
var postMessage = function () {};
|
||||||
var broadcast = function () {};
|
var broadcast = function () {};
|
||||||
var sendDriveEvent = function () {};
|
var sendDriveEvent = function () {};
|
||||||
|
var registerProxyEvents = function () {};
|
||||||
|
|
||||||
var storeHash;
|
var storeHash;
|
||||||
|
|
||||||
var store = window.CryptPad_AsyncStore = {};
|
var store = window.CryptPad_AsyncStore = {};
|
||||||
|
|
||||||
|
|
||||||
var onSync = function (cb) {
|
var onSync = function (cb) {
|
||||||
Realtime.whenRealtimeSyncs(store.realtime, cb);
|
nThen(function (waitFor) {
|
||||||
|
Realtime.whenRealtimeSyncs(store.realtime, waitFor());
|
||||||
|
if (store.sharedFolders) {
|
||||||
|
for (var k in store.sharedFolders) {
|
||||||
|
Realtime.whenRealtimeSyncs(store.sharedFolders[k].realtime, waitFor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).nThen(function () { cb(); });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Store.get = function (clientId, key, cb) {
|
Store.get = function (clientId, key, cb) {
|
||||||
cb(Util.find(store.proxy, key));
|
cb(Util.find(store.proxy, key));
|
||||||
};
|
};
|
||||||
@@ -55,6 +62,13 @@ define([
|
|||||||
onSync(cb);
|
onSync(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Store.getSharedFolder = function (clientId, id, cb) {
|
||||||
|
if (store.manager.folders[id]) {
|
||||||
|
return void cb(store.manager.folders[id].proxy);
|
||||||
|
}
|
||||||
|
cb({});
|
||||||
|
};
|
||||||
|
|
||||||
Store.hasSigningKeys = function () {
|
Store.hasSigningKeys = function () {
|
||||||
if (!store.proxy) { return; }
|
if (!store.proxy) { return; }
|
||||||
return typeof(store.proxy.edPrivate) === 'string' &&
|
return typeof(store.proxy.edPrivate) === 'string' &&
|
||||||
@@ -78,17 +92,9 @@ define([
|
|||||||
if (!userChannel) { return null; }
|
if (!userChannel) { return null; }
|
||||||
|
|
||||||
// Get the list of pads' channel ID in your drive
|
// Get the list of pads' channel ID in your drive
|
||||||
// This list is filtered so that it doesn't include pad owned by other users (you should
|
// This list is filtered so that it doesn't include pad owned by other users
|
||||||
// not pin these pads)
|
// It now includes channels from shared folders
|
||||||
var files = store.userObject.getFiles([store.userObject.FILES_DATA]);
|
var list = store.manager.getChannelsList('pin');
|
||||||
var edPublic = store.proxy.edPublic;
|
|
||||||
var list = files.map(function (id) {
|
|
||||||
var d = store.userObject.getFileData(id);
|
|
||||||
if (d.owners && d.owners.length && edPublic &&
|
|
||||||
d.owners.indexOf(edPublic) === -1) { return; }
|
|
||||||
return d.channel;
|
|
||||||
})
|
|
||||||
.filter(function (x) { return x; });
|
|
||||||
|
|
||||||
// Get the avatar
|
// Get the avatar
|
||||||
var profile = store.proxy.profile;
|
var profile = store.proxy.profile;
|
||||||
@@ -111,19 +117,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var getExpirableChannelList = function () {
|
var getExpirableChannelList = function () {
|
||||||
var list = [];
|
return store.manager.getChannelsList('expirable');
|
||||||
store.userObject.getFiles([store.userObject.FILES_DATA]).forEach(function (id) {
|
|
||||||
var data = store.userObject.getFileData(id);
|
|
||||||
var edPublic = store.proxy.edPublic;
|
|
||||||
|
|
||||||
// Push channels owned by someone else or channel that should have expired
|
|
||||||
// because of the expiration time
|
|
||||||
if ((data.owners && data.owners.length && data.owners.indexOf(edPublic) === -1) ||
|
|
||||||
(data.expire && data.expire < (+new Date()))) {
|
|
||||||
list.push(data.channel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var getCanonicalChannelList = function (expirable) {
|
var getCanonicalChannelList = function (expirable) {
|
||||||
@@ -380,7 +374,7 @@ define([
|
|||||||
|
|
||||||
Store.getDeletedPads = function (clientId, data, cb) {
|
Store.getDeletedPads = function (clientId, data, cb) {
|
||||||
if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); }
|
if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); }
|
||||||
var list = getCanonicalChannelList(true);
|
var list = (data && data.list) || getCanonicalChannelList(true);
|
||||||
if (!Array.isArray(list)) {
|
if (!Array.isArray(list)) {
|
||||||
return void cb({error: 'INVALID_FILE_LIST'});
|
return void cb({error: 'INVALID_FILE_LIST'});
|
||||||
}
|
}
|
||||||
@@ -435,10 +429,11 @@ define([
|
|||||||
cb(JSON.parse(JSON.stringify(metadata)));
|
cb(JSON.parse(JSON.stringify(metadata)));
|
||||||
};
|
};
|
||||||
|
|
||||||
var makePad = function (href, title) {
|
var makePad = function (href, roHref, title) {
|
||||||
var now = +new Date();
|
var now = +new Date();
|
||||||
return {
|
return {
|
||||||
href: href,
|
href: href,
|
||||||
|
roHref: roHref,
|
||||||
atime: now,
|
atime: now,
|
||||||
ctime: now,
|
ctime: now,
|
||||||
title: title || Hash.getDefaultName(Hash.parsePadUrl(href)),
|
title: title || Hash.getDefaultName(Hash.parsePadUrl(href)),
|
||||||
@@ -446,16 +441,21 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
Store.addPad = function (clientId, data, cb) {
|
Store.addPad = function (clientId, data, cb) {
|
||||||
if (!data.href) { return void cb({error:'NO_HREF'}); }
|
if (!data.href && !data.roHref) { return void cb({error:'NO_HREF'}); }
|
||||||
var pad = makePad(data.href, data.title);
|
if (!data.roHref) {
|
||||||
|
var parsed = Hash.parsePadUrl(data.href);
|
||||||
|
if (parsed.hashData.type === "pad") {
|
||||||
|
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
|
||||||
|
data.roHref = '/' + parsed.type + '/#' + Hash.getViewHashFromKeys(secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var pad = makePad(data.href, data.roHref, data.title);
|
||||||
if (data.owners) { pad.owners = data.owners; }
|
if (data.owners) { pad.owners = data.owners; }
|
||||||
if (data.expire) { pad.expire = data.expire; }
|
if (data.expire) { pad.expire = data.expire; }
|
||||||
if (data.password) { pad.password = data.password; }
|
if (data.password) { pad.password = data.password; }
|
||||||
if (data.channel) { pad.channel = data.channel; }
|
if (data.channel) { pad.channel = data.channel; }
|
||||||
store.userObject.pushData(pad, function (e, id) {
|
store.manager.addPad(data.path, pad, function (e) {
|
||||||
if (e) { return void cb({error: "Error while adding a template:"+ e}); }
|
if (e) { return void cb({error: "Error while adding the pad:"+ e}); }
|
||||||
var path = data.path || ['root'];
|
|
||||||
store.userObject.add(id, path);
|
|
||||||
sendDriveEvent('DRIVE_CHANGE', {
|
sendDriveEvent('DRIVE_CHANGE', {
|
||||||
path: ['drive', UserObject.FILES_DATA]
|
path: ['drive', UserObject.FILES_DATA]
|
||||||
}, clientId);
|
}, clientId);
|
||||||
@@ -464,17 +464,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var getOwnedPads = function () {
|
var getOwnedPads = function () {
|
||||||
var list = [];
|
var list = store.manager.getChannelsList('owned');
|
||||||
store.userObject.getFiles([store.userObject.FILES_DATA]).forEach(function (id) {
|
|
||||||
var data = store.userObject.getFileData(id);
|
|
||||||
var edPublic = store.proxy.edPublic;
|
|
||||||
|
|
||||||
// Push channels owned by someone else or channel that should have expired
|
|
||||||
// because of the expiration time
|
|
||||||
if (data.owners && data.owners.length === 1 && data.owners.indexOf(edPublic) !== -1) {
|
|
||||||
list.push(data.channel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (store.proxy.todo) {
|
if (store.proxy.todo) {
|
||||||
// No password for todo
|
// No password for todo
|
||||||
list.push(Hash.hrefToHexChannelId('/todo/#' + store.proxy.todo, null));
|
list.push(Hash.hrefToHexChannelId('/todo/#' + store.proxy.todo, null));
|
||||||
@@ -596,33 +586,6 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var getAttributeObject = function (attr) {
|
|
||||||
if (typeof attr === "string") {
|
|
||||||
console.error('DEPRECATED: use setAttribute with an array, not a string');
|
|
||||||
return {
|
|
||||||
path: ['settings'],
|
|
||||||
obj: store.proxy.settings,
|
|
||||||
key: attr
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!Array.isArray(attr)) { return void console.error("Attribute must be string or array"); }
|
|
||||||
if (attr.length === 0) { return void console.error("Attribute can't be empty"); }
|
|
||||||
var obj = store.proxy.settings;
|
|
||||||
attr.forEach(function (el, i) {
|
|
||||||
if (i === attr.length-1) { return; }
|
|
||||||
if (!obj[el]) {
|
|
||||||
obj[el] = {};
|
|
||||||
}
|
|
||||||
else if (typeof obj[el] !== "object") { return void console.error("Wrong attribute"); }
|
|
||||||
obj = obj[el];
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
path: ['settings'].concat(attr),
|
|
||||||
obj: obj,
|
|
||||||
key: attr[attr.length-1]
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set the display name (username) in the proxy
|
// Set the display name (username) in the proxy
|
||||||
Store.setDisplayName = function (clientId, value, cb) {
|
Store.setDisplayName = function (clientId, value, cb) {
|
||||||
store.proxy[Constants.displayNameKey] = value;
|
store.proxy[Constants.displayNameKey] = value;
|
||||||
@@ -651,7 +614,7 @@ define([
|
|||||||
* - value (String)
|
* - value (String)
|
||||||
*/
|
*/
|
||||||
Store.setPadAttribute = function (clientId, data, cb) {
|
Store.setPadAttribute = function (clientId, data, cb) {
|
||||||
store.userObject.setPadAttribute(data.href, data.attr, data.value, function () {
|
store.manager.setPadAttribute(data, function () {
|
||||||
sendDriveEvent('DRIVE_CHANGE', {
|
sendDriveEvent('DRIVE_CHANGE', {
|
||||||
path: ['drive', UserObject.FILES_DATA]
|
path: ['drive', UserObject.FILES_DATA]
|
||||||
}, clientId);
|
}, clientId);
|
||||||
@@ -659,11 +622,38 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
Store.getPadAttribute = function (clientId, data, cb) {
|
Store.getPadAttribute = function (clientId, data, cb) {
|
||||||
store.userObject.getPadAttribute(data.href, data.attr, function (err, val) {
|
store.manager.getPadAttribute(data, function (err, val) {
|
||||||
if (err) { return void cb({error: err}); }
|
if (err) { return void cb({error: err}); }
|
||||||
cb(val);
|
cb(val);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var getAttributeObject = function (attr) {
|
||||||
|
if (typeof attr === "string") {
|
||||||
|
console.error('DEPRECATED: use setAttribute with an array, not a string');
|
||||||
|
return {
|
||||||
|
path: ['settings'],
|
||||||
|
obj: store.proxy.settings,
|
||||||
|
key: attr
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!Array.isArray(attr)) { return void console.error("Attribute must be string or array"); }
|
||||||
|
if (attr.length === 0) { return void console.error("Attribute can't be empty"); }
|
||||||
|
var obj = store.proxy.settings;
|
||||||
|
attr.forEach(function (el, i) {
|
||||||
|
if (i === attr.length-1) { return; }
|
||||||
|
if (!obj[el]) {
|
||||||
|
obj[el] = {};
|
||||||
|
}
|
||||||
|
else if (typeof obj[el] !== "object") { return void console.error("Wrong attribute"); }
|
||||||
|
obj = obj[el];
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
path: ['settings'].concat(attr),
|
||||||
|
obj: obj,
|
||||||
|
key: attr[attr.length-1]
|
||||||
|
};
|
||||||
|
};
|
||||||
Store.setAttribute = function (clientId, data, cb) {
|
Store.setAttribute = function (clientId, data, cb) {
|
||||||
try {
|
try {
|
||||||
var object = getAttributeObject(data.attr);
|
var object = getAttributeObject(data.attr);
|
||||||
@@ -681,11 +671,12 @@ define([
|
|||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
Store.listAllTags = function (clientId, data, cb) {
|
Store.listAllTags = function (clientId, data, cb) {
|
||||||
cb(store.userObject.getTagsList());
|
cb(store.manager.getTagsList());
|
||||||
};
|
};
|
||||||
|
|
||||||
// Templates
|
// Templates
|
||||||
Store.getTemplates = function (clientId, data, cb) {
|
Store.getTemplates = function (clientId, data, cb) {
|
||||||
|
// No templates in shared folders: we don't need the manager here
|
||||||
var templateFiles = store.userObject.getFiles(['template']);
|
var templateFiles = store.userObject.getFiles(['template']);
|
||||||
var res = [];
|
var res = [];
|
||||||
templateFiles.forEach(function (f) {
|
templateFiles.forEach(function (f) {
|
||||||
@@ -695,6 +686,7 @@ define([
|
|||||||
cb(res);
|
cb(res);
|
||||||
};
|
};
|
||||||
Store.incrementTemplateUse = function (clientId, href) {
|
Store.incrementTemplateUse = function (clientId, href) {
|
||||||
|
// No templates in shared folders: we don't need the manager here
|
||||||
store.userObject.getPadAttribute(href, 'used', function (err, data) {
|
store.userObject.getPadAttribute(href, 'used', function (err, data) {
|
||||||
// This is a not critical function, abort in case of error to make sure we won't
|
// This is a not critical function, abort in case of error to make sure we won't
|
||||||
// create any issue with the user object or the async store
|
// create any issue with the user object or the async store
|
||||||
@@ -705,6 +697,17 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Pads
|
// Pads
|
||||||
|
Store.isOnlyInSharedFolder = function (clientId, channel, cb) {
|
||||||
|
var res = store.manager.findChannel(channel);
|
||||||
|
|
||||||
|
// A pad is only in a shared worker if:
|
||||||
|
// 1. this pad is in at least one proxy
|
||||||
|
// 2. no proxy containing this pad is the main drive
|
||||||
|
return cb (res.length && !res.some(function (obj) {
|
||||||
|
// Main drive doesn't have an fId (folder ID)
|
||||||
|
return !obj.fId;
|
||||||
|
}));
|
||||||
|
};
|
||||||
Store.moveToTrash = function (clientId, data, cb) {
|
Store.moveToTrash = function (clientId, data, cb) {
|
||||||
var href = Hash.getRelativeHref(data.href);
|
var href = Hash.getRelativeHref(data.href);
|
||||||
store.userObject.forget(href);
|
store.userObject.forget(href);
|
||||||
@@ -728,78 +731,48 @@ define([
|
|||||||
if (channelData && channelData.wc && channel === channelData.wc.id) {
|
if (channelData && channelData.wc && channel === channelData.wc.id) {
|
||||||
owners = channelData.data.owners || undefined;
|
owners = channelData.data.owners || undefined;
|
||||||
}
|
}
|
||||||
|
if (data.owners) {
|
||||||
|
owners = data.owners;
|
||||||
|
}
|
||||||
|
|
||||||
var expire;
|
var expire;
|
||||||
if (channelData && channelData.wc && channel === channelData.wc.id) {
|
if (channelData && channelData.wc && channel === channelData.wc.id) {
|
||||||
expire = +channelData.data.expire || undefined;
|
expire = +channelData.data.expire || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
var allPads = Util.find(store.proxy, ['drive', 'filesData']) || {};
|
var datas = store.manager.findChannel(channel);
|
||||||
var isStronger;
|
var contains = datas.length !== 0;
|
||||||
|
datas.forEach(function (obj) {
|
||||||
// If we don't find the new channel in our existing pads, we'll have to add the pads
|
var pad = obj.data;
|
||||||
// to filesData
|
pad.atime = +new Date();
|
||||||
var contains;
|
pad.title = title;
|
||||||
|
if (owners || h.type !== "file") {
|
||||||
// Update all pads that use the same channel but with a weaker hash
|
// OWNED_FILES
|
||||||
// Edit > Edit (present) > View > View (present)
|
// Never remove owner for files
|
||||||
for (var id in allPads) {
|
pad.owners = owners;
|
||||||
var pad = allPads[id];
|
|
||||||
if (!pad.href) { continue; }
|
|
||||||
|
|
||||||
var p2 = Hash.parsePadUrl(pad.href);
|
|
||||||
var h2 = p2.hashData;
|
|
||||||
|
|
||||||
// Different types, proceed to the next one
|
|
||||||
// No hash data: corrupted pad?
|
|
||||||
if (p.type !== p2.type || !h2) { continue; }
|
|
||||||
// Different channel: continue
|
|
||||||
if (pad.channel !== channel) { continue; }
|
|
||||||
|
|
||||||
var shouldUpdate = p.hash.replace(/\/$/, '') === p2.hash.replace(/\/$/, '');
|
|
||||||
|
|
||||||
// If the hash is different but represents the same channel, check if weaker or stronger
|
|
||||||
if (!shouldUpdate && h.version !== 0) {
|
|
||||||
// We had view & now we have edit, update
|
|
||||||
if (h2.mode === 'view' && h.mode === 'edit') { shouldUpdate = true; }
|
|
||||||
// Same mode and we had present URL, update
|
|
||||||
else if (h.mode === h2.mode && h2.present) { shouldUpdate = true; }
|
|
||||||
// If we're here it means we have a weaker URL:
|
|
||||||
// update the date but keep the existing hash
|
|
||||||
else {
|
|
||||||
pad.atime = +new Date();
|
|
||||||
contains = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pad.expire = expire;
|
||||||
|
if (h.mode === 'view') { return; }
|
||||||
|
|
||||||
if (shouldUpdate) {
|
// If we only have rohref, it means we have a stronger href
|
||||||
contains = true;
|
if (!pad.href) {
|
||||||
pad.atime = +new Date();
|
// If we have a stronger url, remove the possible weaker from the trash.
|
||||||
pad.title = title;
|
// If all of the weaker ones were in the trash, add the stronger to ROOT
|
||||||
if (owners || h.type !== "file") {
|
obj.userObject.restoreHref(href);
|
||||||
// OWNED_FILES
|
|
||||||
// Never remove owner for files
|
|
||||||
pad.owners = owners;
|
|
||||||
}
|
|
||||||
pad.expire = expire;
|
|
||||||
|
|
||||||
// If the href is different, it means we have a stronger one
|
|
||||||
if (href !== pad.href) { isStronger = true; }
|
|
||||||
pad.href = href;
|
|
||||||
}
|
}
|
||||||
}
|
pad.href = href;
|
||||||
|
});
|
||||||
if (isStronger) {
|
|
||||||
// If we have a stronger url, remove the possible weaker from the trash.
|
|
||||||
// If all of the weaker ones were in the trash, add the stronger to ROOT
|
|
||||||
store.userObject.restoreHref(href);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the pad if it does not exist in our drive
|
// Add the pad if it does not exist in our drive
|
||||||
if (!contains) {
|
if (!contains) {
|
||||||
|
var roHref;
|
||||||
|
if (h.mode === "view") {
|
||||||
|
roHref = href;
|
||||||
|
href = undefined;
|
||||||
|
}
|
||||||
Store.addPad(clientId, {
|
Store.addPad(clientId, {
|
||||||
href: href,
|
href: href,
|
||||||
|
roHref: roHref,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
title: title,
|
title: title,
|
||||||
owners: owners,
|
owners: owners,
|
||||||
@@ -819,7 +792,6 @@ define([
|
|||||||
// Filepicker app
|
// Filepicker app
|
||||||
Store.getSecureFilesList = function (clientId, query, cb) {
|
Store.getSecureFilesList = function (clientId, query, cb) {
|
||||||
var list = {};
|
var list = {};
|
||||||
var hashes = [];
|
|
||||||
var types = query.types;
|
var types = query.types;
|
||||||
var where = query.where;
|
var where = query.where;
|
||||||
var filter = query.filter || {};
|
var filter = query.filter || {};
|
||||||
@@ -834,19 +806,19 @@ define([
|
|||||||
}
|
}
|
||||||
return filtered;
|
return filtered;
|
||||||
};
|
};
|
||||||
store.userObject.getFiles(where).forEach(function (id) {
|
store.manager.getSecureFilesList(where).forEach(function (obj) {
|
||||||
var data = store.userObject.getFileData(id);
|
var data = obj.data;
|
||||||
var parsed = Hash.parsePadUrl(data.href);
|
var id = obj.id;
|
||||||
|
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||||
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
|
if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) &&
|
||||||
hashes.indexOf(parsed.hash) === -1 &&
|
|
||||||
!isFiltered(parsed.type, data)) {
|
!isFiltered(parsed.type, data)) {
|
||||||
hashes.push(parsed.hash);
|
|
||||||
list[id] = data;
|
list[id] = data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cb(list);
|
cb(list);
|
||||||
};
|
};
|
||||||
Store.getPadData = function (clientId, id, cb) {
|
Store.getPadData = function (clientId, id, cb) {
|
||||||
|
// FIXME: this is only used for templates at the moment, so we don't need the manager
|
||||||
cb(store.userObject.getFileData(id));
|
cb(store.userObject.getFileData(id));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1192,37 +1164,60 @@ define([
|
|||||||
}]));
|
}]));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// SHARED FOLDERS
|
||||||
|
var loadSharedFolder = function (id, data, cb) {
|
||||||
|
var parsed = Hash.parsePadUrl(data.href);
|
||||||
|
var secret = Hash.getSecrets('drive', parsed.hash, data.password);
|
||||||
|
var owners = data.owners;
|
||||||
|
var listmapConfig = {
|
||||||
|
data: {},
|
||||||
|
websocketURL: NetConfig.getWebsocketURL(),
|
||||||
|
channel: secret.channel,
|
||||||
|
readOnly: false,
|
||||||
|
validateKey: secret.keys.validateKey || undefined,
|
||||||
|
crypto: Crypto.createEncryptor(secret.keys),
|
||||||
|
userName: 'sharedFolder',
|
||||||
|
logLevel: 1,
|
||||||
|
ChainPad: ChainPad,
|
||||||
|
classic: true,
|
||||||
|
owners: owners
|
||||||
|
};
|
||||||
|
var rt = Listmap.create(listmapConfig);
|
||||||
|
store.sharedFolders[id] = rt;
|
||||||
|
rt.proxy.on('ready', function (info) {
|
||||||
|
store.manager.addProxy(id, rt.proxy, info.leave);
|
||||||
|
cb(rt, info.metadata);
|
||||||
|
});
|
||||||
|
if (store.driveEvents) {
|
||||||
|
registerProxyEvents(rt.proxy, id);
|
||||||
|
}
|
||||||
|
return rt;
|
||||||
|
};
|
||||||
|
Store.addSharedFolder = function (clientId, data, cb) {
|
||||||
|
Store.userObjectCommand(clientId, {
|
||||||
|
cmd: 'addSharedFolder',
|
||||||
|
data: data
|
||||||
|
}, cb);
|
||||||
|
};
|
||||||
|
|
||||||
// Drive
|
// Drive
|
||||||
Store.userObjectCommand = function (clientId, cmdData, cb) {
|
Store.userObjectCommand = function (clientId, cmdData, cb) {
|
||||||
if (!cmdData || !cmdData.cmd) { return; }
|
if (!cmdData || !cmdData.cmd) { return; }
|
||||||
var data = cmdData.data;
|
//var data = cmdData.data;
|
||||||
var cb2 = function (data2) {
|
var cb2 = function (data2) {
|
||||||
var paths = data.paths || [data.path] || [];
|
//var paths = data.paths || [data.path] || [];
|
||||||
paths = paths.concat(data.newPath || []);
|
//paths = paths.concat(data.newPath ? [data.newPath] : []);
|
||||||
paths.forEach(function (p) {
|
//paths.forEach(function (p) {
|
||||||
sendDriveEvent('DRIVE_CHANGE', {
|
sendDriveEvent('DRIVE_CHANGE', {
|
||||||
//path: ['drive', UserObject.FILES_DATA]
|
path: ['drive', UserObject.FILES_DATA]
|
||||||
path: ['drive'].concat(p)
|
//path: ['drive'].concat(p)
|
||||||
}, clientId);
|
}, clientId);
|
||||||
|
//});
|
||||||
|
onSync(function () {
|
||||||
|
cb(data2);
|
||||||
});
|
});
|
||||||
cb(data2);
|
|
||||||
};
|
};
|
||||||
switch (cmdData.cmd) {
|
store.manager.command(cmdData, cb2);
|
||||||
case 'move':
|
|
||||||
store.userObject.move(data.paths, data.newPath, cb2); break;
|
|
||||||
case 'restore':
|
|
||||||
store.userObject.restore(data.path, cb2); break;
|
|
||||||
case 'addFolder':
|
|
||||||
store.userObject.addFolder(data.path, data.name, cb2); break;
|
|
||||||
case 'delete':
|
|
||||||
store.userObject.delete(data.paths, cb2, data.nocheck, data.isOwnPadRemoved); break;
|
|
||||||
case 'emptyTrash':
|
|
||||||
store.userObject.emptyTrash(cb2); break;
|
|
||||||
case 'rename':
|
|
||||||
store.userObject.rename(data.path, data.newName, cb2); break;
|
|
||||||
default:
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Clients management
|
// Clients management
|
||||||
@@ -1259,32 +1254,41 @@ define([
|
|||||||
|
|
||||||
// Special events
|
// Special events
|
||||||
|
|
||||||
var driveEventInit = false;
|
|
||||||
sendDriveEvent = function (q, data, sender) {
|
sendDriveEvent = function (q, data, sender) {
|
||||||
driveEventClients.forEach(function (cId) {
|
driveEventClients.forEach(function (cId) {
|
||||||
if (cId === sender) { return; }
|
if (cId === sender) { return; }
|
||||||
postMessage(cId, q, data);
|
postMessage(cId, q, data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
registerProxyEvents = function (proxy, fId) {
|
||||||
|
proxy.on('change', [], function (o, n, p) {
|
||||||
|
sendDriveEvent('DRIVE_CHANGE', {
|
||||||
|
id: fId,
|
||||||
|
old: o,
|
||||||
|
new: n,
|
||||||
|
path: p
|
||||||
|
});
|
||||||
|
});
|
||||||
|
proxy.on('remove', [], function (o, p) {
|
||||||
|
sendDriveEvent('DRIVE_REMOVE', {
|
||||||
|
id: fId,
|
||||||
|
old: o,
|
||||||
|
path: p
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Store._subscribeToDrive = function (clientId) {
|
Store._subscribeToDrive = function (clientId) {
|
||||||
if (driveEventClients.indexOf(clientId) === -1) {
|
if (driveEventClients.indexOf(clientId) === -1) {
|
||||||
driveEventClients.push(clientId);
|
driveEventClients.push(clientId);
|
||||||
}
|
}
|
||||||
if (!driveEventInit) {
|
if (!store.driveEvents) {
|
||||||
store.proxy.on('change', [], function (o, n, p) {
|
store.driveEvents = true;
|
||||||
sendDriveEvent('DRIVE_CHANGE', {
|
registerProxyEvents(store.proxy);
|
||||||
old: o,
|
Object.keys(store.manager.folders).forEach(function (fId) {
|
||||||
new: n,
|
var proxy = store.manager.folders[fId].proxy;
|
||||||
path: p
|
registerProxyEvents(proxy, fId);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
store.proxy.on('remove', [], function (o, p) {
|
|
||||||
sendDriveEvent(clientId, 'DRIVE_REMOVE', {
|
|
||||||
old: o,
|
|
||||||
path: p
|
|
||||||
});
|
|
||||||
});
|
|
||||||
driveEventInit = true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1340,12 +1344,60 @@ define([
|
|||||||
/////////////////////// Init /////////////////////////////////////
|
/////////////////////// Init /////////////////////////////////////
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var loadSharedFolders = function (waitFor) {
|
||||||
|
store.sharedFolders = {};
|
||||||
|
var shared = Util.find(store.proxy, ['drive', UserObject.SHARED_FOLDERS]) || {};
|
||||||
|
// Check if any of our shared folder is expired or deleted by its owner.
|
||||||
|
// If we don't check now, Listmap will create an empty proxy if it no longer exists on
|
||||||
|
// the server.
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
var edPublic = store.proxy.edPublic;
|
||||||
|
var checkExpired = Object.keys(shared).filter(function (fId) {
|
||||||
|
var d = shared[fId];
|
||||||
|
return (Array.isArray(d.owners) && d.owners.length &&
|
||||||
|
(!edPublic || d.owners.indexOf(edPublic) === -1))
|
||||||
|
|| (d.expire && d.expire < (+new Date()));
|
||||||
|
}).map(function (fId) {
|
||||||
|
return shared[fId].channel;
|
||||||
|
});
|
||||||
|
Store.getDeletedPads(null, {list: checkExpired}, waitFor(function (chans) {
|
||||||
|
if (chans && chans.error) { return void console.error(chans.error); }
|
||||||
|
if (!Array.isArray(chans) || !chans.length) { return; }
|
||||||
|
var toDelete = [];
|
||||||
|
Object.keys(shared).forEach(function (fId) {
|
||||||
|
if (chans.indexOf(shared[fId].channel) !== -1
|
||||||
|
&& toDelete.indexOf(fId) === -1) {
|
||||||
|
toDelete.push(fId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
toDelete.forEach(function (fId) {
|
||||||
|
var paths = store.userObject.findFile(Number(fId));
|
||||||
|
store.userObject.delete(paths, waitFor(), true);
|
||||||
|
delete shared[fId];
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
Object.keys(shared).forEach(function (id) {
|
||||||
|
var sf = shared[id];
|
||||||
|
loadSharedFolder(id, sf, waitFor());
|
||||||
|
});
|
||||||
|
}).nThen(waitFor());
|
||||||
|
};
|
||||||
|
|
||||||
var onReady = function (clientId, returned, cb) {
|
var onReady = function (clientId, returned, cb) {
|
||||||
var proxy = store.proxy;
|
var proxy = store.proxy;
|
||||||
var userObject = store.userObject = UserObject.init(proxy.drive, {
|
var unpin = function (data, cb) {
|
||||||
pinPads: function (data, cb) { Store.pinPads(null, data, cb); },
|
if (!store.loggedIn) { return void cb(); }
|
||||||
unpinPads: function (data, cb) { Store.unpinPads(null, data, cb); },
|
Store.unpinPads(null, data, cb);
|
||||||
removeOwnedChannel: function (data, cb) { Store.removeOwnedChannel(null, data, cb); },
|
};
|
||||||
|
var pin = function (data, cb) {
|
||||||
|
if (!store.loggedIn) { return void cb(); }
|
||||||
|
Store.pinPads(null, data, cb);
|
||||||
|
};
|
||||||
|
var manager = store.manager = ProxyManager.create(proxy.drive, proxy.edPublic,
|
||||||
|
pin, unpin, loadSharedFolder, {
|
||||||
|
outer: true,
|
||||||
|
removeOwnedChannel: function (data, cb) { Store.removeOwnedChannel('', data, cb); },
|
||||||
edPublic: store.proxy.edPublic,
|
edPublic: store.proxy.edPublic,
|
||||||
loggedIn: store.loggedIn,
|
loggedIn: store.loggedIn,
|
||||||
log: function (msg) {
|
log: function (msg) {
|
||||||
@@ -1353,6 +1405,7 @@ define([
|
|||||||
sendDriveEvent("DRIVE_LOG", msg);
|
sendDriveEvent("DRIVE_LOG", msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
var userObject = store.userObject = manager.user.userObject;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
postMessage(clientId, 'LOADING_DRIVE', {
|
postMessage(clientId, 'LOADING_DRIVE', {
|
||||||
state: 2
|
state: 2
|
||||||
@@ -1361,16 +1414,18 @@ define([
|
|||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
Migrate(proxy, waitFor(), function (version, progress) {
|
Migrate(proxy, waitFor(), function (version, progress) {
|
||||||
postMessage(clientId, 'LOADING_DRIVE', {
|
postMessage(clientId, 'LOADING_DRIVE', {
|
||||||
state: 2,
|
state: (2 + (version / 10)),
|
||||||
progress: progress
|
progress: progress
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).nThen(function () {
|
Store.initAnonRpc(null, null, waitFor());
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
postMessage(clientId, 'LOADING_DRIVE', {
|
postMessage(clientId, 'LOADING_DRIVE', {
|
||||||
state: 3
|
state: 3
|
||||||
});
|
});
|
||||||
userObject.fixFiles();
|
userObject.fixFiles();
|
||||||
|
loadSharedFolders(waitFor);
|
||||||
|
}).nThen(function () {
|
||||||
var requestLogin = function () {
|
var requestLogin = function () {
|
||||||
broadcast([], "REQUEST_LOGIN");
|
broadcast([], "REQUEST_LOGIN");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,127 +19,130 @@ var debug = function (msg) { console.log(msg); };
|
|||||||
var init = function (client, cb) {
|
var init = function (client, cb) {
|
||||||
debug('SW INIT');
|
debug('SW INIT');
|
||||||
|
|
||||||
require([
|
require(['/api/config?cb=' + (+new Date()).toString(16)], function (ApiConfig) {
|
||||||
'/common/requireconfig.js'
|
if (ApiConfig.requireConf) { require.config(ApiConfig.requireConf); }
|
||||||
], function (RequireConfig) {
|
|
||||||
require.config(RequireConfig());
|
|
||||||
require([
|
require([
|
||||||
'/common/common-util.js',
|
'/common/requireconfig.js'
|
||||||
'/common/outer/worker-channel.js',
|
], function (RequireConfig) {
|
||||||
'/common/outer/store-rpc.js'
|
require.config(RequireConfig());
|
||||||
], function (Util, Channel, SRpc) {
|
require([
|
||||||
debug('SW Required ressources loaded');
|
'/common/common-util.js',
|
||||||
var msgEv = Util.mkEvent();
|
'/common/outer/worker-channel.js',
|
||||||
|
'/common/outer/store-rpc.js'
|
||||||
|
], function (Util, Channel, SRpc) {
|
||||||
|
debug('SW Required ressources loaded');
|
||||||
|
var msgEv = Util.mkEvent();
|
||||||
|
|
||||||
if (!self.Rpc) {
|
if (!self.Rpc) {
|
||||||
self.Rpc = SRpc();
|
self.Rpc = SRpc();
|
||||||
}
|
}
|
||||||
var Rpc = self.Rpc;
|
var Rpc = self.Rpc;
|
||||||
|
|
||||||
var postToClient = function (data) {
|
var postToClient = function (data) {
|
||||||
postMsg(client, data);
|
postMsg(client, data);
|
||||||
};
|
};
|
||||||
Channel.create(msgEv, postToClient, function (chan) {
|
Channel.create(msgEv, postToClient, function (chan) {
|
||||||
debug('SW Channel created');
|
debug('SW Channel created');
|
||||||
|
|
||||||
var clientId = client.id;
|
var clientId = client.id;
|
||||||
self.tabs[clientId].chan = chan;
|
self.tabs[clientId].chan = chan;
|
||||||
Object.keys(Rpc.queries).forEach(function (q) {
|
Object.keys(Rpc.queries).forEach(function (q) {
|
||||||
if (q === 'CONNECT') { return; }
|
if (q === 'CONNECT') { return; }
|
||||||
if (q === 'JOIN_PAD') { return; }
|
if (q === 'JOIN_PAD') { return; }
|
||||||
if (q === 'SEND_PAD_MSG') { return; }
|
if (q === 'SEND_PAD_MSG') { return; }
|
||||||
chan.on(q, function (data, cb) {
|
chan.on(q, function (data, cb) {
|
||||||
try {
|
try {
|
||||||
Rpc.queries[q](clientId, data, cb);
|
Rpc.queries[q](clientId, data, cb);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error in webworker when executing query ' + q);
|
console.error('Error in webworker when executing query ' + q);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}
|
}
|
||||||
if (q === "DISCONNECT") {
|
if (q === "DISCONNECT") {
|
||||||
console.log('Deleting existing store!');
|
console.log('Deleting existing store!');
|
||||||
delete self.Rpc;
|
delete self.Rpc;
|
||||||
delete self.store;
|
delete self.store;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
chan.on('CONNECT', function (cfg, cb) {
|
|
||||||
debug('SW Connect callback');
|
|
||||||
if (self.store) {
|
|
||||||
debug('Store already exists!');
|
|
||||||
if (cfg.driveEvents) {
|
|
||||||
Rpc._subscribeToDrive(clientId);
|
|
||||||
}
|
|
||||||
if (cfg.messenger) {
|
|
||||||
Rpc._subscribeToMessenger(clientId);
|
|
||||||
}
|
|
||||||
return void cb(self.store);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug('Loading new async store');
|
|
||||||
// One-time initialization (init async-store)
|
|
||||||
cfg.query = function (cId, cmd, data, cb) {
|
|
||||||
cb = cb || function () {};
|
|
||||||
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
|
||||||
if (err) { return void cb({error: err}); }
|
|
||||||
cb(data2);
|
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
cfg.broadcast = function (excludes, cmd, data, cb) {
|
chan.on('CONNECT', function (cfg, cb) {
|
||||||
cb = cb || function () {};
|
debug('SW Connect callback');
|
||||||
Object.keys(self.tabs).forEach(function (cId) {
|
if (self.store) {
|
||||||
if (excludes.indexOf(cId) !== -1) { return; }
|
debug('Store already exists!');
|
||||||
|
if (cfg.driveEvents) {
|
||||||
|
Rpc._subscribeToDrive(clientId);
|
||||||
|
}
|
||||||
|
if (cfg.messenger) {
|
||||||
|
Rpc._subscribeToMessenger(clientId);
|
||||||
|
}
|
||||||
|
return void cb(self.store);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Loading new async store');
|
||||||
|
// One-time initialization (init async-store)
|
||||||
|
cfg.query = function (cId, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
||||||
if (err) { return void cb({error: err}); }
|
if (err) { return void cb({error: err}); }
|
||||||
cb(data2);
|
cb(data2);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
cfg.broadcast = function (excludes, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
|
Object.keys(self.tabs).forEach(function (cId) {
|
||||||
|
if (excludes.indexOf(cId) !== -1) { return; }
|
||||||
|
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(data2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
||||||
|
if (cfg.driveEvents) {
|
||||||
|
Rpc._subscribeToDrive(clientId);
|
||||||
|
}
|
||||||
|
if (cfg.messenger) {
|
||||||
|
Rpc._subscribeToMessenger(clientId);
|
||||||
|
}
|
||||||
|
if (data && data.state === "ALREADY_INIT") {
|
||||||
|
return void cb(data.returned);
|
||||||
|
}
|
||||||
|
self.store = data;
|
||||||
|
cb(data);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
|
||||||
if (cfg.driveEvents) {
|
|
||||||
Rpc._subscribeToDrive(clientId);
|
|
||||||
}
|
|
||||||
if (cfg.messenger) {
|
|
||||||
Rpc._subscribeToMessenger(clientId);
|
|
||||||
}
|
|
||||||
if (data && data.state === "ALREADY_INIT") {
|
|
||||||
return void cb(data.returned);
|
|
||||||
}
|
|
||||||
self.store = data;
|
|
||||||
cb(data);
|
|
||||||
});
|
});
|
||||||
});
|
chan.on('JOIN_PAD', function (data, cb) {
|
||||||
chan.on('JOIN_PAD', function (data, cb) {
|
self.tabs[clientId].channelId = data.channel;
|
||||||
self.tabs[clientId].channelId = data.channel;
|
try {
|
||||||
try {
|
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
||||||
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error('Error in webworker when executing query JOIN_PAD');
|
||||||
console.error('Error in webworker when executing query JOIN_PAD');
|
console.error(e);
|
||||||
console.error(e);
|
console.log(data);
|
||||||
console.log(data);
|
}
|
||||||
}
|
});
|
||||||
});
|
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
||||||
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
var data = {
|
||||||
var data = {
|
msg: msg,
|
||||||
msg: msg,
|
channel: self.tabs[clientId].channelId
|
||||||
channel: self.tabs[clientId].channelId
|
};
|
||||||
};
|
try {
|
||||||
try {
|
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
||||||
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
||||||
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
console.error(e);
|
||||||
console.error(e);
|
console.log(data);
|
||||||
console.log(data);
|
}
|
||||||
}
|
});
|
||||||
});
|
cb();
|
||||||
cb();
|
}, true);
|
||||||
}, true);
|
|
||||||
|
|
||||||
self.tabs[client.id].msgEv = msgEv;
|
self.tabs[client.id].msgEv = msgEv;
|
||||||
|
|
||||||
self.tabs[client.id].close = function () {
|
self.tabs[client.id].close = function () {
|
||||||
Rpc._removeClient(client.id);
|
Rpc._removeClient(client.id);
|
||||||
};
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,128 +19,131 @@ var debug = function (msg) { console.log(msg); };
|
|||||||
var init = function (client, cb) {
|
var init = function (client, cb) {
|
||||||
debug('SharedW INIT');
|
debug('SharedW INIT');
|
||||||
|
|
||||||
require([
|
require(['/api/config?cb=' + (+new Date()).toString(16)], function (ApiConfig) {
|
||||||
'/common/requireconfig.js'
|
if (ApiConfig.requireConf) { require.config(ApiConfig.requireConf); }
|
||||||
], function (RequireConfig) {
|
|
||||||
require.config(RequireConfig());
|
|
||||||
require([
|
require([
|
||||||
'/common/common-util.js',
|
'/common/requireconfig.js'
|
||||||
'/common/outer/worker-channel.js',
|
], function (RequireConfig) {
|
||||||
'/common/outer/store-rpc.js'
|
require.config(RequireConfig());
|
||||||
], function (Util, Channel, SRpc) {
|
require([
|
||||||
debug('SharedW Required ressources loaded');
|
'/common/common-util.js',
|
||||||
var msgEv = Util.mkEvent();
|
'/common/outer/worker-channel.js',
|
||||||
|
'/common/outer/store-rpc.js'
|
||||||
|
], function (Util, Channel, SRpc) {
|
||||||
|
debug('SharedW Required ressources loaded');
|
||||||
|
var msgEv = Util.mkEvent();
|
||||||
|
|
||||||
if (!self.Rpc) {
|
if (!self.Rpc) {
|
||||||
self.Rpc = SRpc();
|
self.Rpc = SRpc();
|
||||||
}
|
}
|
||||||
var Rpc = self.Rpc;
|
var Rpc = self.Rpc;
|
||||||
|
|
||||||
var postToClient = function (data) {
|
var postToClient = function (data) {
|
||||||
postMsg(client, data);
|
postMsg(client, data);
|
||||||
};
|
};
|
||||||
Channel.create(msgEv, postToClient, function (chan) {
|
Channel.create(msgEv, postToClient, function (chan) {
|
||||||
debug('SharedW Channel created');
|
debug('SharedW Channel created');
|
||||||
|
|
||||||
var clientId = client.id;
|
var clientId = client.id;
|
||||||
client.chan = chan;
|
client.chan = chan;
|
||||||
Object.keys(Rpc.queries).forEach(function (q) {
|
Object.keys(Rpc.queries).forEach(function (q) {
|
||||||
if (q === 'CONNECT') { return; }
|
if (q === 'CONNECT') { return; }
|
||||||
if (q === 'JOIN_PAD') { return; }
|
if (q === 'JOIN_PAD') { return; }
|
||||||
if (q === 'SEND_PAD_MSG') { return; }
|
if (q === 'SEND_PAD_MSG') { return; }
|
||||||
chan.on(q, function (data, cb) {
|
chan.on(q, function (data, cb) {
|
||||||
try {
|
try {
|
||||||
Rpc.queries[q](clientId, data, cb);
|
Rpc.queries[q](clientId, data, cb);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error in webworker when executing query ' + q);
|
console.error('Error in webworker when executing query ' + q);
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}
|
}
|
||||||
if (q === "DISCONNECT") {
|
if (q === "DISCONNECT") {
|
||||||
console.log('Deleting existing store!');
|
console.log('Deleting existing store!');
|
||||||
delete self.Rpc;
|
delete self.Rpc;
|
||||||
delete self.store;
|
delete self.store;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
chan.on('CONNECT', function (cfg, cb) {
|
|
||||||
debug('SharedW connecting to store...');
|
|
||||||
if (self.store) {
|
|
||||||
debug('Store already exists!');
|
|
||||||
if (cfg.driveEvents) {
|
|
||||||
Rpc._subscribeToDrive(clientId);
|
|
||||||
}
|
|
||||||
if (cfg.messenger) {
|
|
||||||
Rpc._subscribeToMessenger(clientId);
|
|
||||||
}
|
|
||||||
return void cb(self.store);
|
|
||||||
}
|
|
||||||
|
|
||||||
debug('Loading new async store');
|
|
||||||
// One-time initialization (init async-store)
|
|
||||||
cfg.query = function (cId, cmd, data, cb) {
|
|
||||||
cb = cb || function () {};
|
|
||||||
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
|
||||||
if (err) { return void cb({error: err}); }
|
|
||||||
cb(data2);
|
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
cfg.broadcast = function (excludes, cmd, data, cb) {
|
chan.on('CONNECT', function (cfg, cb) {
|
||||||
cb = cb || function () {};
|
debug('SharedW connecting to store...');
|
||||||
Object.keys(self.tabs).forEach(function (cId) {
|
if (self.store) {
|
||||||
if (excludes.indexOf(cId) !== -1) { return; }
|
debug('Store already exists!');
|
||||||
|
if (cfg.driveEvents) {
|
||||||
|
Rpc._subscribeToDrive(clientId);
|
||||||
|
}
|
||||||
|
if (cfg.messenger) {
|
||||||
|
Rpc._subscribeToMessenger(clientId);
|
||||||
|
}
|
||||||
|
return void cb(self.store);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('Loading new async store');
|
||||||
|
// One-time initialization (init async-store)
|
||||||
|
cfg.query = function (cId, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
||||||
if (err) { return void cb({error: err}); }
|
if (err) { return void cb({error: err}); }
|
||||||
cb(data2);
|
cb(data2);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
cfg.broadcast = function (excludes, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
|
Object.keys(self.tabs).forEach(function (cId) {
|
||||||
|
if (excludes.indexOf(cId) !== -1) { return; }
|
||||||
|
self.tabs[cId].chan.query(cmd, data, function (err, data2) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(data2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
||||||
|
if (cfg.driveEvents) {
|
||||||
|
Rpc._subscribeToDrive(clientId);
|
||||||
|
}
|
||||||
|
if (cfg.messenger) {
|
||||||
|
Rpc._subscribeToMessenger(clientId);
|
||||||
|
}
|
||||||
|
if (data && data.state === "ALREADY_INIT") {
|
||||||
|
self.store = data.returned;
|
||||||
|
return void cb(data.returned);
|
||||||
|
}
|
||||||
|
self.store = data;
|
||||||
|
cb(data);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
|
||||||
if (cfg.driveEvents) {
|
|
||||||
Rpc._subscribeToDrive(clientId);
|
|
||||||
}
|
|
||||||
if (cfg.messenger) {
|
|
||||||
Rpc._subscribeToMessenger(clientId);
|
|
||||||
}
|
|
||||||
if (data && data.state === "ALREADY_INIT") {
|
|
||||||
self.store = data.returned;
|
|
||||||
return void cb(data.returned);
|
|
||||||
}
|
|
||||||
self.store = data;
|
|
||||||
cb(data);
|
|
||||||
});
|
});
|
||||||
});
|
chan.on('JOIN_PAD', function (data, cb) {
|
||||||
chan.on('JOIN_PAD', function (data, cb) {
|
client.channelId = data.channel;
|
||||||
client.channelId = data.channel;
|
try {
|
||||||
try {
|
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
||||||
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error('Error in webworker when executing query JOIN_PAD');
|
||||||
console.error('Error in webworker when executing query JOIN_PAD');
|
console.error(e);
|
||||||
console.error(e);
|
console.log(data);
|
||||||
console.log(data);
|
}
|
||||||
}
|
});
|
||||||
});
|
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
||||||
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
var data = {
|
||||||
var data = {
|
msg: msg,
|
||||||
msg: msg,
|
channel: client.channelId
|
||||||
channel: client.channelId
|
};
|
||||||
};
|
try {
|
||||||
try {
|
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
||||||
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
} catch (e) {
|
||||||
} catch (e) {
|
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
||||||
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
console.error(e);
|
||||||
console.error(e);
|
console.log(data);
|
||||||
console.log(data);
|
}
|
||||||
}
|
});
|
||||||
});
|
cb();
|
||||||
cb();
|
}, true);
|
||||||
}, true);
|
|
||||||
|
|
||||||
client.msgEv = msgEv;
|
client.msgEv = msgEv;
|
||||||
|
|
||||||
client.close = function () {
|
client.close = function () {
|
||||||
Rpc._removeClient(client.id);
|
Rpc._removeClient(client.id);
|
||||||
};
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ define([
|
|||||||
MOVE_TO_TRASH: Store.moveToTrash,
|
MOVE_TO_TRASH: Store.moveToTrash,
|
||||||
RESET_DRIVE: Store.resetDrive,
|
RESET_DRIVE: Store.resetDrive,
|
||||||
GET_METADATA: Store.getMetadata,
|
GET_METADATA: Store.getMetadata,
|
||||||
|
IS_ONLY_IN_SHARED_FOLDER: Store.isOnlyInSharedFolder,
|
||||||
SET_DISPLAY_NAME: Store.setDisplayName,
|
SET_DISPLAY_NAME: Store.setDisplayName,
|
||||||
SET_PAD_ATTRIBUTE: Store.setPadAttribute,
|
SET_PAD_ATTRIBUTE: Store.setPadAttribute,
|
||||||
GET_PAD_ATTRIBUTE: Store.getPadAttribute,
|
GET_PAD_ATTRIBUTE: Store.getPadAttribute,
|
||||||
@@ -53,6 +54,8 @@ define([
|
|||||||
GET_PAD_DATA: Store.getPadData,
|
GET_PAD_DATA: Store.getPadData,
|
||||||
GET_STRONGER_HASH: Store.getStrongerHash,
|
GET_STRONGER_HASH: Store.getStrongerHash,
|
||||||
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
|
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
|
||||||
|
GET_SHARED_FOLDER: Store.getSharedFolder,
|
||||||
|
ADD_SHARED_FOLDER: Store.addSharedFolder,
|
||||||
// Messaging
|
// Messaging
|
||||||
INVITE_FROM_USERLIST: Store.inviteFromUserlist,
|
INVITE_FROM_USERLIST: Store.inviteFromUserlist,
|
||||||
ADD_DIRECT_MESSAGE_HANDLERS: Store.addDirectMessageHandlers,
|
ADD_DIRECT_MESSAGE_HANDLERS: Store.addDirectMessageHandlers,
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ define([
|
|||||||
href: href,
|
href: href,
|
||||||
path: path,
|
path: path,
|
||||||
password: password,
|
password: password,
|
||||||
channel: id
|
channel: id,
|
||||||
|
owners: metadata.owners
|
||||||
};
|
};
|
||||||
common.setPadTitle(data, function (err) {
|
common.setPadTitle(data, function (err) {
|
||||||
if (err) { return void console.error(err); }
|
if (err) { return void console.error(err); }
|
||||||
|
|||||||
@@ -14,15 +14,11 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.init = function (config, exp, files) {
|
module.init = function (config, exp, files) {
|
||||||
var unpinPads = config.unpinPads || function () {
|
|
||||||
console.error("unpinPads was not provided");
|
|
||||||
};
|
|
||||||
var pinPads = config.pinPads;
|
|
||||||
var removeOwnedChannel = config.removeOwnedChannel || function () {
|
var removeOwnedChannel = config.removeOwnedChannel || function () {
|
||||||
console.error("removeOwnedChannel was not provided");
|
console.error("removeOwnedChannel was not provided");
|
||||||
};
|
};
|
||||||
var loggedIn = config.loggedIn;
|
var loggedIn = config.loggedIn;
|
||||||
var workgroup = config.workgroup;
|
var sharedFolder = config.sharedFolder;
|
||||||
var edPublic = config.edPublic;
|
var edPublic = config.edPublic;
|
||||||
|
|
||||||
var ROOT = exp.ROOT;
|
var ROOT = exp.ROOT;
|
||||||
@@ -31,6 +27,7 @@ define([
|
|||||||
var UNSORTED = exp.UNSORTED;
|
var UNSORTED = exp.UNSORTED;
|
||||||
var TRASH = exp.TRASH;
|
var TRASH = exp.TRASH;
|
||||||
var TEMPLATE = exp.TEMPLATE;
|
var TEMPLATE = exp.TEMPLATE;
|
||||||
|
var SHARED_FOLDERS = exp.SHARED_FOLDERS;
|
||||||
|
|
||||||
var debug = exp.debug;
|
var debug = exp.debug;
|
||||||
|
|
||||||
@@ -50,35 +47,31 @@ define([
|
|||||||
var data = exp.getFileData(id);
|
var data = exp.getFileData(id);
|
||||||
cb(null, clone(data[attr]));
|
cb(null, clone(data[attr]));
|
||||||
};
|
};
|
||||||
var removePadAttribute = exp.removePadAttribute = function (f) {
|
|
||||||
if (typeof(f) !== 'string') {
|
|
||||||
console.error("Can't find pad attribute for an undefined pad");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Object.keys(files).forEach(function (key) {
|
|
||||||
var hash = f.indexOf('#') !== -1 ? f.slice(f.indexOf('#') + 1) : null;
|
|
||||||
if (hash && key.indexOf(hash) === 0) {
|
|
||||||
exp.debug("Deleting pad attribute in the realtime object");
|
|
||||||
delete files[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
exp.pushData = function (data, cb) {
|
exp.pushData = function (data, cb) {
|
||||||
if (typeof cb !== "function") { cb = function () {}; }
|
if (typeof cb !== "function") { cb = function () {}; }
|
||||||
var todo = function () {
|
var id = Util.createRandomInteger();
|
||||||
var id = Util.createRandomInteger();
|
files[FILES_DATA][id] = data;
|
||||||
files[FILES_DATA][id] = data;
|
cb(null, id);
|
||||||
cb(null, id);
|
};
|
||||||
};
|
|
||||||
if (!loggedIn || !AppConfig.enablePinning || config.testMode) {
|
exp.pushSharedFolder = function (data, cb) {
|
||||||
return void todo();
|
if (typeof cb !== "function") { cb = function () {}; }
|
||||||
|
|
||||||
|
// Check if we already have this shared folder in our drive
|
||||||
|
if (Object.keys(files[SHARED_FOLDERS]).some(function (k) {
|
||||||
|
return files[SHARED_FOLDERS][k].channel === data.channel;
|
||||||
|
})) {
|
||||||
|
return void cb ('EEXISTS');
|
||||||
}
|
}
|
||||||
if (!pinPads) { return; }
|
|
||||||
pinPads([data.channel], function (obj) {
|
// Add the folder
|
||||||
if (obj && obj.error) { return void cb(obj.error); }
|
if (!loggedIn || !AppConfig.enablePinning || config.testMode) {
|
||||||
todo();
|
return void cb("EAUTH");
|
||||||
});
|
}
|
||||||
|
var id = Util.createRandomInteger();
|
||||||
|
files[SHARED_FOLDERS][id] = data;
|
||||||
|
cb(null, id);
|
||||||
};
|
};
|
||||||
|
|
||||||
// FILES DATA
|
// FILES DATA
|
||||||
@@ -87,21 +80,21 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Find files in FILES_DATA that are not anymore in the drive, and remove them from
|
// Find files in FILES_DATA that are not anymore in the drive, and remove them from
|
||||||
// FILES_DATA. If there are owned pads, remove them from server too, unless the flag tells
|
// FILES_DATA. If there are owned pads, remove them from server too.
|
||||||
// us they're already removed
|
exp.checkDeletedFiles = function (cb) {
|
||||||
exp.checkDeletedFiles = function (isOwnPadRemoved) {
|
if (!loggedIn && !config.testMode) { return void cb(); }
|
||||||
// Nothing in FILES_DATA for workgroups
|
|
||||||
if (workgroup || (!loggedIn && !config.testMode)) { return; }
|
|
||||||
|
|
||||||
var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]);
|
var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]);
|
||||||
var toClean = [];
|
var toClean = [];
|
||||||
exp.getFiles([FILES_DATA]).forEach(function (id) {
|
var ownedRemoved = [];
|
||||||
|
exp.getFiles([FILES_DATA, SHARED_FOLDERS]).forEach(function (id) {
|
||||||
if (filesList.indexOf(id) === -1) {
|
if (filesList.indexOf(id) === -1) {
|
||||||
var fd = exp.getFileData(id);
|
var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
|
||||||
var channelId = fd.channel;
|
var channelId = fd.channel;
|
||||||
// If trying to remove an owned pad, remove it from server also
|
// If trying to remove an owned pad, remove it from server also
|
||||||
if (!isOwnPadRemoved &&
|
if (!sharedFolder && fd.owners && fd.owners.indexOf(edPublic) !== -1
|
||||||
fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) {
|
&& channelId) {
|
||||||
|
if (channelId) { ownedRemoved.push(channelId); }
|
||||||
removeOwnedChannel(channelId, function (obj) {
|
removeOwnedChannel(channelId, function (obj) {
|
||||||
if (obj && obj.error) {
|
if (obj && obj.error) {
|
||||||
// If the error is that the file is already removed, nothing to
|
// If the error is that the file is already removed, nothing to
|
||||||
@@ -116,14 +109,15 @@ define([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (channelId) { toClean.push(channelId); }
|
if (channelId) { toClean.push(channelId); }
|
||||||
spliceFileData(id);
|
if (exp.isSharedFolder(id)) {
|
||||||
|
delete files[SHARED_FOLDERS][id];
|
||||||
|
} else {
|
||||||
|
spliceFileData(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!toClean.length) { return; }
|
if (!toClean.length) { return void cb(); }
|
||||||
unpinPads(toClean, function (response) {
|
cb(null, toClean, ownedRemoved);
|
||||||
if (response && response.error) { return console.error(response.error); }
|
|
||||||
// console.error(response);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
var deleteHrefs = function (ids) {
|
var deleteHrefs = function (ids) {
|
||||||
ids.forEach(function (obj) {
|
ids.forEach(function (obj) {
|
||||||
@@ -137,7 +131,7 @@ define([
|
|||||||
files[TRASH][obj.name].splice(idx, 1);
|
files[TRASH][obj.name].splice(idx, 1);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
exp.deleteMultiplePermanently = function (paths, nocheck, isOwnPadRemoved) {
|
exp.deleteMultiplePermanently = function (paths, nocheck, cb) {
|
||||||
var hrefPaths = paths.filter(function(x) { return exp.isPathIn(x, ['hrefArray']); });
|
var hrefPaths = paths.filter(function(x) { return exp.isPathIn(x, ['hrefArray']); });
|
||||||
var rootPaths = paths.filter(function(x) { return exp.isPathIn(x, [ROOT]); });
|
var rootPaths = paths.filter(function(x) { return exp.isPathIn(x, [ROOT]); });
|
||||||
var trashPaths = paths.filter(function(x) { return exp.isPathIn(x, [TRASH]); });
|
var trashPaths = paths.filter(function(x) { return exp.isPathIn(x, [TRASH]); });
|
||||||
@@ -145,14 +139,11 @@ define([
|
|||||||
|
|
||||||
if (!loggedIn && !config.testMode) {
|
if (!loggedIn && !config.testMode) {
|
||||||
allFilesPaths.forEach(function (path) {
|
allFilesPaths.forEach(function (path) {
|
||||||
var el = exp.find(path);
|
var id = path[1];
|
||||||
if (!el) { return; }
|
|
||||||
var id = exp.getIdFromHref(el.href);
|
|
||||||
if (!id) { return; }
|
if (!id) { return; }
|
||||||
spliceFileData(id);
|
spliceFileData(id);
|
||||||
removePadAttribute(el.href);
|
|
||||||
});
|
});
|
||||||
return;
|
return void cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
var ids = [];
|
var ids = [];
|
||||||
@@ -192,11 +183,69 @@ define([
|
|||||||
deleteMultipleTrashRoot(trashRoot);
|
deleteMultipleTrashRoot(trashRoot);
|
||||||
|
|
||||||
// In some cases, we want to remove pads from a location without removing them from
|
// In some cases, we want to remove pads from a location without removing them from
|
||||||
// OLD_FILES_DATA (replaceHref)
|
// FILES_DATA (replaceHref)
|
||||||
if (!nocheck) { exp.checkDeletedFiles(isOwnPadRemoved); }
|
if (!nocheck) { exp.checkDeletedFiles(cb); }
|
||||||
|
else { cb(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Move
|
// Move
|
||||||
|
|
||||||
|
// From another drive
|
||||||
|
exp.copyFromOtherDrive = function (path, element, data, key) {
|
||||||
|
// Copy files data
|
||||||
|
// We have to remove pads that are already in the current proxy to make sure
|
||||||
|
// we won't create duplicates
|
||||||
|
|
||||||
|
var toRemove = [];
|
||||||
|
Object.keys(data).forEach(function (id) {
|
||||||
|
id = Number(id);
|
||||||
|
// Find and maybe update existing pads with the same channel id
|
||||||
|
var d = data[id];
|
||||||
|
var found = false;
|
||||||
|
for (var i in files[FILES_DATA]) {
|
||||||
|
if (files[FILES_DATA][i].channel === d.channel) {
|
||||||
|
// Update href?
|
||||||
|
if (!files[FILES_DATA][i].href) { files[FILES_DATA][i].href = d.href; }
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
toRemove.push(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
files[FILES_DATA][id] = data[id];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove existing pads from the "element" variable
|
||||||
|
if (exp.isFile(element) && toRemove.indexOf(element) !== -1) {
|
||||||
|
exp.log(Messages.sharedFolders_duplicate);
|
||||||
|
return;
|
||||||
|
} else if (exp.isFolder(element)) {
|
||||||
|
var _removeExisting = function (root) {
|
||||||
|
for (var k in root) {
|
||||||
|
if (exp.isFile(root[k])) {
|
||||||
|
if (toRemove.indexOf(root[k]) !== -1) {
|
||||||
|
exp.log(Messages.sharedFolders_duplicate);
|
||||||
|
delete root[k];
|
||||||
|
}
|
||||||
|
} else if (exp.isFolder(root[k])) {
|
||||||
|
_removeExisting(root[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_removeExisting(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Copy file or folder
|
||||||
|
var newParent = exp.find(path);
|
||||||
|
var tempName = exp.isFile(element) ? Hash.createChannelId() : key;
|
||||||
|
var newName = exp.getAvailableName(newParent, tempName);
|
||||||
|
newParent[newName] = element;
|
||||||
|
};
|
||||||
|
|
||||||
|
// From the same drive
|
||||||
var pushToTrash = function (name, element, path) {
|
var pushToTrash = function (name, element, path) {
|
||||||
var trash = files[TRASH];
|
var trash = files[TRASH];
|
||||||
if (typeof(trash[name]) === "undefined") { trash[name] = []; }
|
if (typeof(trash[name]) === "undefined") { trash[name] = []; }
|
||||||
@@ -259,7 +308,6 @@ define([
|
|||||||
if (!id) { return; }
|
if (!id) { return; }
|
||||||
if (!loggedIn && !config.testMode) {
|
if (!loggedIn && !config.testMode) {
|
||||||
// delete permanently
|
// delete permanently
|
||||||
exp.removePadAttribute(href);
|
|
||||||
spliceFileData(id);
|
spliceFileData(id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -268,14 +316,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
// REPLACE
|
// REPLACE
|
||||||
exp.replace = function (o, n) {
|
// If all the occurences of an href are in the trash, remove them and add the file in root.
|
||||||
var idO = exp.getIdFromHref(o);
|
|
||||||
if (!idO || !exp.isFile(idO)) { return; }
|
|
||||||
var data = exp.getFileData(idO);
|
|
||||||
if (!data) { return; }
|
|
||||||
data.href = n;
|
|
||||||
};
|
|
||||||
// If all the occurences of an href are in the trash, remvoe them and add the file in root.
|
|
||||||
// This is use with setPadTitle when we open a stronger version of a deleted pad
|
// This is use with setPadTitle when we open a stronger version of a deleted pad
|
||||||
exp.restoreHref = function (href) {
|
exp.restoreHref = function (href) {
|
||||||
var idO = exp.getIdFromHref(href);
|
var idO = exp.getIdFromHref(href);
|
||||||
@@ -300,9 +341,9 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
exp.add = function (id, path) {
|
exp.add = function (id, path) {
|
||||||
// TODO WW
|
|
||||||
if (!loggedIn && !config.testMode) { return; }
|
if (!loggedIn && !config.testMode) { return; }
|
||||||
var data = files[FILES_DATA][id];
|
id = Number(id);
|
||||||
|
var data = files[FILES_DATA][id] || files[SHARED_FOLDERS][id];
|
||||||
if (!data || typeof(data) !== "object") { return; }
|
if (!data || typeof(data) !== "object") { return; }
|
||||||
var newPath = path, parentEl;
|
var newPath = path, parentEl;
|
||||||
if (path && !Array.isArray(path)) {
|
if (path && !Array.isArray(path)) {
|
||||||
@@ -406,7 +447,6 @@ define([
|
|||||||
});
|
});
|
||||||
delete files[OLD_FILES_DATA];
|
delete files[OLD_FILES_DATA];
|
||||||
delete files.migrate;
|
delete files.migrate;
|
||||||
console.log('done');
|
|
||||||
todo();
|
todo();
|
||||||
};
|
};
|
||||||
if (exp.rt) {
|
if (exp.rt) {
|
||||||
@@ -473,6 +513,7 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
var fixTrashRoot = function () {
|
var fixTrashRoot = function () {
|
||||||
|
if (sharedFolder) { return; }
|
||||||
if (typeof(files[TRASH]) !== "object") { debug("TRASH was not an object"); files[TRASH] = {}; }
|
if (typeof(files[TRASH]) !== "object") { debug("TRASH was not an object"); files[TRASH] = {}; }
|
||||||
var tr = files[TRASH];
|
var tr = files[TRASH];
|
||||||
var toClean;
|
var toClean;
|
||||||
@@ -516,6 +557,7 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
var fixTemplate = function () {
|
var fixTemplate = function () {
|
||||||
|
if (sharedFolder) { return; }
|
||||||
if (!Array.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; }
|
if (!Array.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; }
|
||||||
files[TEMPLATE] = Util.deduplicateString(files[TEMPLATE].slice());
|
files[TEMPLATE] = Util.deduplicateString(files[TEMPLATE].slice());
|
||||||
var us = files[TEMPLATE];
|
var us = files[TEMPLATE];
|
||||||
@@ -547,7 +589,7 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
var fixFilesData = function () {
|
var fixFilesData = function () {
|
||||||
if (typeof files[FILES_DATA] !== "object") { debug("OLD_FILES_DATA was not an object"); files[FILES_DATA] = {}; }
|
if (typeof files[FILES_DATA] !== "object") { debug("FILES_DATA was not an object"); files[FILES_DATA] = {}; }
|
||||||
var fd = files[FILES_DATA];
|
var fd = files[FILES_DATA];
|
||||||
var rootFiles = exp.getFiles([ROOT, TRASH, 'hrefArray']);
|
var rootFiles = exp.getFiles([ROOT, TRASH, 'hrefArray']);
|
||||||
var root = exp.find([ROOT]);
|
var root = exp.find([ROOT]);
|
||||||
@@ -563,33 +605,45 @@ define([
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Clean missing href
|
// Clean missing href
|
||||||
var parsed;
|
if (!el.href && !el.roHref) {
|
||||||
if (el.href) {
|
|
||||||
if (!el.href) {
|
|
||||||
debug("Removing an element in filesData with a missing href.", el);
|
|
||||||
toClean.push(id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
parsed = Hash.parsePadUrl(el.href);
|
|
||||||
// Clean invalid hash
|
|
||||||
if (!parsed.hash) {
|
|
||||||
debug("Removing an element in filesData with a invalid href.", el);
|
|
||||||
toClean.push(id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Clean invalid type
|
|
||||||
if (!parsed.type) {
|
|
||||||
debug("Removing an element in filesData with a invalid type.", el);
|
|
||||||
toClean.push(id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (!el.roHref) {
|
|
||||||
debug("Removing an element in filesData with a missing href.", el);
|
debug("Removing an element in filesData with a missing href.", el);
|
||||||
toClean.push(id);
|
toClean.push(id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parsed = Hash.parsePadUrl(el.href || el.roHref);
|
||||||
|
var secret;
|
||||||
|
|
||||||
|
// Clean invalid hash
|
||||||
|
if (!parsed.hash) {
|
||||||
|
debug("Removing an element in filesData with a invalid href.", el);
|
||||||
|
toClean.push(id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Clean invalid type
|
||||||
|
if (!parsed.type) {
|
||||||
|
debug("Removing an element in filesData with a invalid type.", el);
|
||||||
|
toClean.push(id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an edit link, check the view link
|
||||||
|
if (el.href && parsed.hashData.type === "pad") {
|
||||||
|
if (parsed.hashData.mode === "view") {
|
||||||
|
el.roHref = el.href;
|
||||||
|
delete el.href;
|
||||||
|
} else if (!el.roHref) {
|
||||||
|
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
||||||
|
el.roHref = '/' + parsed.type + '/#' + Hash.getViewHashFromKeys(secret);
|
||||||
|
} else {
|
||||||
|
var parsed2 = Hash.parsePadUrl(el.roHref);
|
||||||
|
if (!parsed2.hash || !parsed2.type) {
|
||||||
|
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
||||||
|
el.roHref = '/' + parsed.type + '/#' + Hash.getViewHashFromKeys(secret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fix href
|
// Fix href
|
||||||
if (el.href && /^https*:\/\//.test(el.href)) { el.href = Hash.getRelativeHref(el.href); }
|
if (el.href && /^https*:\/\//.test(el.href)) { el.href = Hash.getRelativeHref(el.href); }
|
||||||
// Fix creation time
|
// Fix creation time
|
||||||
@@ -597,11 +651,14 @@ define([
|
|||||||
// Fix title
|
// Fix title
|
||||||
if (!el.title) { el.title = Hash.getDefaultName(parsed); }
|
if (!el.title) { el.title = Hash.getDefaultName(parsed); }
|
||||||
// Fix channel
|
// Fix channel
|
||||||
if (el.href && !el.channel) {
|
if (!el.channel) {
|
||||||
try {
|
try {
|
||||||
var secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
if (!secret) {
|
||||||
|
secret = Hash.getSecrets(parsed.type, parsed.hash, el.password);
|
||||||
|
}
|
||||||
el.channel = secret.channel;
|
el.channel = secret.channel;
|
||||||
console.log('Adding missing channel in filesData ', el.channel);
|
console.log(el);
|
||||||
|
debug('Adding missing channel in filesData ', el.channel);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -618,6 +675,21 @@ define([
|
|||||||
spliceFileData(id);
|
spliceFileData(id);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
var fixSharedFolders = function () {
|
||||||
|
if (sharedFolder) { return; }
|
||||||
|
if (typeof(files[SHARED_FOLDERS]) !== "object") { debug("SHARED_FOLDER was not an object"); files[SHARED_FOLDERS] = {}; }
|
||||||
|
var sf = files[SHARED_FOLDERS];
|
||||||
|
var rootFiles = exp.getFiles([ROOT]);
|
||||||
|
var root = exp.find([ROOT]);
|
||||||
|
for (var id in sf) {
|
||||||
|
id = Number(id);
|
||||||
|
if (rootFiles.indexOf(id) === -1) {
|
||||||
|
console.log('missing' + id);
|
||||||
|
var newName = Hash.createChannelId();
|
||||||
|
root[newName] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var fixDrive = function () {
|
var fixDrive = function () {
|
||||||
Object.keys(files).forEach(function (key) {
|
Object.keys(files).forEach(function (key) {
|
||||||
@@ -627,11 +699,10 @@ define([
|
|||||||
|
|
||||||
fixRoot();
|
fixRoot();
|
||||||
fixTrashRoot();
|
fixTrashRoot();
|
||||||
if (!workgroup) {
|
fixTemplate();
|
||||||
fixTemplate();
|
fixFilesData();
|
||||||
fixFilesData();
|
|
||||||
}
|
|
||||||
fixDrive();
|
fixDrive();
|
||||||
|
fixSharedFolders();
|
||||||
|
|
||||||
if (JSON.stringify(files) !== before) {
|
if (JSON.stringify(files) !== before) {
|
||||||
debug("Your file system was corrupted. It has been cleaned so that the pads you visit can be stored safely");
|
debug("Your file system was corrupted. It has been cleaned so that the pads you visit can be stored safely");
|
||||||
|
|||||||
@@ -7,94 +7,97 @@ localStorage = {
|
|||||||
getItem: function (k) { return localStorage[k]; }
|
getItem: function (k) { return localStorage[k]; }
|
||||||
};
|
};
|
||||||
|
|
||||||
require([
|
require(['/api/config?cb=' + (+new Date()).toString(16)], function (ApiConfig) {
|
||||||
'/common/requireconfig.js'
|
if (ApiConfig.requireConf) { require.config(ApiConfig.requireConf); }
|
||||||
], function (RequireConfig) {
|
|
||||||
require.config(RequireConfig());
|
|
||||||
require([
|
require([
|
||||||
'/common/common-util.js',
|
'/common/requireconfig.js'
|
||||||
'/common/outer/worker-channel.js',
|
], function (RequireConfig) {
|
||||||
'/common/outer/store-rpc.js'
|
require.config(RequireConfig());
|
||||||
], function (Util, Channel, SRpc) {
|
require([
|
||||||
var msgEv = Util.mkEvent();
|
'/common/common-util.js',
|
||||||
|
'/common/outer/worker-channel.js',
|
||||||
|
'/common/outer/store-rpc.js'
|
||||||
|
], function (Util, Channel, SRpc) {
|
||||||
|
var msgEv = Util.mkEvent();
|
||||||
|
|
||||||
var Rpc = SRpc();
|
var Rpc = SRpc();
|
||||||
|
|
||||||
Channel.create(msgEv, postMessage, function (chan) {
|
Channel.create(msgEv, postMessage, function (chan) {
|
||||||
var clientId = '1';
|
var clientId = '1';
|
||||||
Object.keys(Rpc.queries).forEach(function (q) {
|
Object.keys(Rpc.queries).forEach(function (q) {
|
||||||
if (q === 'CONNECT') { return; }
|
if (q === 'CONNECT') { return; }
|
||||||
if (q === 'JOIN_PAD') { return; }
|
if (q === 'JOIN_PAD') { return; }
|
||||||
if (q === 'SEND_PAD_MSG') { return; }
|
if (q === 'SEND_PAD_MSG') { return; }
|
||||||
chan.on(q, function (data, cb) {
|
chan.on(q, function (data, cb) {
|
||||||
|
try {
|
||||||
|
Rpc.queries[q](clientId, data, cb);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error in webworker when executing query ' + q);
|
||||||
|
console.error(e);
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
chan.on('CONNECT', function (cfg, cb) {
|
||||||
|
// load Store here, with cfg, and pass a "query" (chan.query)
|
||||||
|
// cId is a clientId used in ServiceWorker or SharedWorker
|
||||||
|
cfg.query = function (cId, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
|
chan.query(cmd, data, function (err, data2) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(data2);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
cfg.broadcast = function (excludes, cmd, data, cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
|
if (excludes.indexOf(clientId) !== -1) { return; }
|
||||||
|
chan.query(cmd, data, function (err, data2) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(data2);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
||||||
|
if (data && data.state === "ALREADY_INIT") {
|
||||||
|
return void cb(data);
|
||||||
|
}
|
||||||
|
if (cfg.driveEvents) {
|
||||||
|
Rpc._subscribeToDrive(clientId);
|
||||||
|
}
|
||||||
|
if (cfg.messenger) {
|
||||||
|
Rpc._subscribeToMessenger(clientId);
|
||||||
|
}
|
||||||
|
cb(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var chanId;
|
||||||
|
chan.on('JOIN_PAD', function (data, cb) {
|
||||||
|
chanId = data.channel;
|
||||||
try {
|
try {
|
||||||
Rpc.queries[q](clientId, data, cb);
|
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error in webworker when executing query ' + q);
|
console.error('Error in webworker when executing query JOIN_PAD');
|
||||||
console.error(e);
|
console.error(e);
|
||||||
console.log(data);
|
console.log(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
||||||
chan.on('CONNECT', function (cfg, cb) {
|
var data = {
|
||||||
// load Store here, with cfg, and pass a "query" (chan.query)
|
msg: msg,
|
||||||
// cId is a clientId used in ServiceWorker or SharedWorker
|
channel: chanId
|
||||||
cfg.query = function (cId, cmd, data, cb) {
|
};
|
||||||
cb = cb || function () {};
|
try {
|
||||||
chan.query(cmd, data, function (err, data2) {
|
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
||||||
if (err) { return void cb({error: err}); }
|
} catch (e) {
|
||||||
cb(data2);
|
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
||||||
});
|
console.error(e);
|
||||||
};
|
console.log(data);
|
||||||
cfg.broadcast = function (excludes, cmd, data, cb) {
|
|
||||||
cb = cb || function () {};
|
|
||||||
if (excludes.indexOf(clientId) !== -1) { return; }
|
|
||||||
chan.query(cmd, data, function (err, data2) {
|
|
||||||
if (err) { return void cb({error: err}); }
|
|
||||||
cb(data2);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Rpc.queries['CONNECT'](clientId, cfg, function (data) {
|
|
||||||
if (data && data.state === "ALREADY_INIT") {
|
|
||||||
return void cb(data);
|
|
||||||
}
|
}
|
||||||
if (cfg.driveEvents) {
|
|
||||||
Rpc._subscribeToDrive(clientId);
|
|
||||||
}
|
|
||||||
if (cfg.messenger) {
|
|
||||||
Rpc._subscribeToMessenger(clientId);
|
|
||||||
}
|
|
||||||
cb(data);
|
|
||||||
});
|
});
|
||||||
});
|
}, true);
|
||||||
var chanId;
|
|
||||||
chan.on('JOIN_PAD', function (data, cb) {
|
|
||||||
chanId = data.channel;
|
|
||||||
try {
|
|
||||||
Rpc.queries['JOIN_PAD'](clientId, data, cb);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Error in webworker when executing query JOIN_PAD');
|
|
||||||
console.error(e);
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
chan.on('SEND_PAD_MSG', function (msg, cb) {
|
|
||||||
var data = {
|
|
||||||
msg: msg,
|
|
||||||
channel: chanId
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
Rpc.queries['SEND_PAD_MSG'](clientId, data, cb);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Error in webworker when executing query SEND_PAD_MSG');
|
|
||||||
console.error(e);
|
|
||||||
console.log(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
onmessage = function (e) {
|
onmessage = function (e) {
|
||||||
msgEv.fire(e);
|
msgEv.fire(e);
|
||||||
};
|
};
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ define([
|
|||||||
var chan = {};
|
var chan = {};
|
||||||
|
|
||||||
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
|
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
|
||||||
chan.query = function (q, content, cb) {
|
chan.query = function (q, content, cb, opts) {
|
||||||
var txid = mkTxid();
|
var txid = mkTxid();
|
||||||
|
opts = opts || {};
|
||||||
|
var to = opts.timeout || 30000;
|
||||||
var timeout = setTimeout(function () {
|
var timeout = setTimeout(function () {
|
||||||
delete queries[txid];
|
delete queries[txid];
|
||||||
//console.log("Timeout making query " + q);
|
//console.log("Timeout making query " + q);
|
||||||
}, 30000);
|
}, to);
|
||||||
queries[txid] = function (data, msg) {
|
queries[txid] = function (data, msg) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
delete queries[txid];
|
delete queries[txid];
|
||||||
|
|||||||
1018
www/common/proxy-manager.js
Normal file
1018
www/common/proxy-manager.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,6 @@ define([
|
|||||||
'/bower_components/file-saver/FileSaver.min.js',
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
'less!/customize/src/less2/main.less',
|
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
Hyperjson,
|
Hyperjson,
|
||||||
|
|||||||
@@ -21,16 +21,18 @@ define([
|
|||||||
var chan = {};
|
var chan = {};
|
||||||
|
|
||||||
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
|
// Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
|
||||||
chan.query = function (q, content, cb) {
|
chan.query = function (q, content, cb, opts) {
|
||||||
if (!otherWindow) { throw new Error('not yet initialized'); }
|
if (!otherWindow) { throw new Error('not yet initialized'); }
|
||||||
if (!SFrameProtocol[q]) {
|
if (!SFrameProtocol[q]) {
|
||||||
throw new Error('please only make queries are defined in sframe-protocol.js');
|
throw new Error('please only make queries are defined in sframe-protocol.js');
|
||||||
}
|
}
|
||||||
|
opts = opts || {};
|
||||||
var txid = mkTxid();
|
var txid = mkTxid();
|
||||||
|
var to = opts.timeout || 30000;
|
||||||
var timeout = setTimeout(function () {
|
var timeout = setTimeout(function () {
|
||||||
delete queries[txid];
|
delete queries[txid];
|
||||||
console.log("Timeout making query " + q);
|
console.log("Timeout making query " + q);
|
||||||
}, 30000);
|
}, to);
|
||||||
queries[txid] = function (data, msg) {
|
queries[txid] = function (data, msg) {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
delete queries[txid];
|
delete queries[txid];
|
||||||
|
|||||||
@@ -266,8 +266,12 @@ define([
|
|||||||
isDeleted: isNewFile && window.location.hash.length > 0,
|
isDeleted: isNewFile && window.location.hash.length > 0,
|
||||||
forceCreationScreen: forceCreationScreen,
|
forceCreationScreen: forceCreationScreen,
|
||||||
password: password,
|
password: password,
|
||||||
channel: secret.channel
|
channel: secret.channel,
|
||||||
|
enableSF: localStorage.CryptPad_SF === "1" // TODO to remove when enabled by default
|
||||||
};
|
};
|
||||||
|
if (window.CryptPad_newSharedFolder) {
|
||||||
|
additionalPriv.newSharedFolder = window.CryptPad_newSharedFolder;
|
||||||
|
}
|
||||||
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
|
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
|
||||||
|
|
||||||
if (cfg.addData) {
|
if (cfg.addData) {
|
||||||
@@ -421,10 +425,19 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
sframeChan.on('Q_GET_HISTORY_RANGE', function (data, cb) {
|
sframeChan.on('Q_GET_HISTORY_RANGE', function (data, cb) {
|
||||||
var crypto = Crypto.createEncryptor(secret.keys);
|
var nSecret = secret;
|
||||||
|
if (cfg.isDrive) {
|
||||||
|
var hash = Utils.LocalStore.getUserHash() || Utils.LocalStore.getFSHash();
|
||||||
|
if (hash) {
|
||||||
|
nSecret = Utils.Hash.getSecrets('drive', hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var channel = nSecret.channel;
|
||||||
|
var validate = nSecret.keys.validateKey;
|
||||||
|
var crypto = Crypto.createEncryptor(nSecret.keys);
|
||||||
Cryptpad.getHistoryRange({
|
Cryptpad.getHistoryRange({
|
||||||
channel: secret.channel,
|
channel: channel,
|
||||||
validateKey: secret.keys.validateKey,
|
validateKey: validate,
|
||||||
lastKnownHash: data.lastKnownHash
|
lastKnownHash: data.lastKnownHash
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
cb({
|
cb({
|
||||||
@@ -484,6 +497,12 @@ define([
|
|||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
sframeChan.on('Q_IS_ONLY_IN_SHARED_FOLDER', function (data, cb) {
|
||||||
|
Cryptpad.isOnlyInSharedFolder(secret.channel, function (err, t) {
|
||||||
|
if (err) { return void cb({error: err}); }
|
||||||
|
cb(t);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Present mode URL
|
// Present mode URL
|
||||||
sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) {
|
sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) {
|
||||||
|
|||||||
@@ -112,9 +112,14 @@ define([
|
|||||||
var origin = ctx.metadataMgr.getPrivateData().origin;
|
var origin = ctx.metadataMgr.getPrivateData().origin;
|
||||||
return '<script src="' + origin + '/common/media-tag-nacl.min.js"></script>';
|
return '<script src="' + origin + '/common/media-tag-nacl.min.js"></script>';
|
||||||
};
|
};
|
||||||
funcs.getMediatagFromHref = function () {
|
funcs.getMediatagFromHref = function (obj) {
|
||||||
var data = ctx.metadataMgr.getPrivateData();
|
var data = ctx.metadataMgr.getPrivateData();
|
||||||
var secret = Hash.getSecrets('file', data.availableHashes.fileHash, data.password);
|
var secret;
|
||||||
|
if (obj) {
|
||||||
|
secret = Hash.getSecrets('file', obj.hash, obj.password);
|
||||||
|
} else {
|
||||||
|
secret = Hash.getSecrets('file', data.availableHashes.fileHash, data.password);
|
||||||
|
}
|
||||||
if (secret.keys && secret.channel) {
|
if (secret.keys && secret.channel) {
|
||||||
var key = Hash.encodeBase64(secret.keys && secret.keys.cryptKey);
|
var key = Hash.encodeBase64(secret.keys && secret.keys.cryptKey);
|
||||||
var hexFileName = secret.channel;
|
var hexFileName = secret.channel;
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ define({
|
|||||||
'Q_GET_PAD_ATTRIBUTE': true,
|
'Q_GET_PAD_ATTRIBUTE': true,
|
||||||
'Q_SET_PAD_ATTRIBUTE': true,
|
'Q_SET_PAD_ATTRIBUTE': true,
|
||||||
|
|
||||||
|
// Check if a pad is only in a shared folder or (also) in the main drive.
|
||||||
|
// This allows us to change the behavior of some buttons (trash icon...)
|
||||||
|
'Q_IS_ONLY_IN_SHARED_FOLDER': true,
|
||||||
|
|
||||||
// Open/close the File picker (sent from the iframe to the outside)
|
// Open/close the File picker (sent from the iframe to the outside)
|
||||||
'EV_FILE_PICKER_OPEN': true,
|
'EV_FILE_PICKER_OPEN': true,
|
||||||
'EV_FILE_PICKER_CLOSE': true,
|
'EV_FILE_PICKER_CLOSE': true,
|
||||||
@@ -206,6 +210,7 @@ define({
|
|||||||
// Inner drive needs to send command and receive updates from the async store
|
// Inner drive needs to send command and receive updates from the async store
|
||||||
'Q_DRIVE_USEROBJECT': true,
|
'Q_DRIVE_USEROBJECT': true,
|
||||||
'Q_DRIVE_GETOBJECT': true,
|
'Q_DRIVE_GETOBJECT': true,
|
||||||
|
'Q_DRIVE_RESTORE': true,
|
||||||
// Get the pads deleted from the server by other users to remove them from the drive
|
// Get the pads deleted from the server by other users to remove them from the drive
|
||||||
'Q_DRIVE_GETDELETED': true,
|
'Q_DRIVE_GETDELETED': true,
|
||||||
// Store's userObject need to send log messages to inner to display them in the UI
|
// Store's userObject need to send log messages to inner to display them in the UI
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ define([
|
|||||||
var UNSORTED = module.UNSORTED = "unsorted";
|
var UNSORTED = module.UNSORTED = "unsorted";
|
||||||
var TRASH = module.TRASH = "trash";
|
var TRASH = module.TRASH = "trash";
|
||||||
var TEMPLATE = module.TEMPLATE = "template";
|
var TEMPLATE = module.TEMPLATE = "template";
|
||||||
|
var SHARED_FOLDERS = module.SHARED_FOLDERS = "sharedFolders";
|
||||||
|
|
||||||
module.init = function (files, config) {
|
module.init = function (files, config) {
|
||||||
var exp = {};
|
var exp = {};
|
||||||
var pinPads = config.pinPads;
|
|
||||||
var sframeChan = config.sframeChan;
|
var sframeChan = config.sframeChan;
|
||||||
|
|
||||||
var FILES_DATA = module.FILES_DATA = exp.FILES_DATA = Constants.storageKey;
|
var FILES_DATA = module.FILES_DATA = exp.FILES_DATA = Constants.storageKey;
|
||||||
@@ -28,14 +28,21 @@ define([
|
|||||||
exp.UNSORTED = UNSORTED;
|
exp.UNSORTED = UNSORTED;
|
||||||
exp.TRASH = TRASH;
|
exp.TRASH = TRASH;
|
||||||
exp.TEMPLATE = TEMPLATE;
|
exp.TEMPLATE = TEMPLATE;
|
||||||
|
exp.SHARED_FOLDERS = SHARED_FOLDERS;
|
||||||
|
|
||||||
|
var sharedFolder = exp.sharedFolder = config.sharedFolder;
|
||||||
|
exp.id = config.id;
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
var logging = function () {
|
var logging = function () {
|
||||||
console.log.apply(console, arguments);
|
console.log.apply(console, arguments);
|
||||||
};
|
};
|
||||||
var log = config.log || logging;
|
var log = exp.log = config.log || logging;
|
||||||
var logError = config.logError || logging;
|
var logError = config.logError || logging;
|
||||||
var debug = exp.debug = config.debug || logging;
|
var debug = exp.debug = config.debug || logging;
|
||||||
|
|
||||||
|
exp.fixFiles = function () {}; // Overriden by OuterFO
|
||||||
|
|
||||||
var error = exp.error = function() {
|
var error = exp.error = function() {
|
||||||
if (sframeChan) {
|
if (sframeChan) {
|
||||||
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||||
@@ -46,12 +53,10 @@ define([
|
|||||||
exp.fixFiles();
|
exp.fixFiles();
|
||||||
}
|
}
|
||||||
console.error.apply(console, arguments);
|
console.error.apply(console, arguments);
|
||||||
|
exp.fixFiles();
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: workgroup
|
if (config.outer) {
|
||||||
var workgroup = config.workgroup;
|
|
||||||
|
|
||||||
if (pinPads) {
|
|
||||||
// Extend "exp" with methods used only outside of the iframe (requires access to store)
|
// Extend "exp" with methods used only outside of the iframe (requires access to store)
|
||||||
OuterFO.init(config, exp, files);
|
OuterFO.init(config, exp, files);
|
||||||
}
|
}
|
||||||
@@ -76,7 +81,12 @@ define([
|
|||||||
|
|
||||||
var compareFiles = function (fileA, fileB) { return fileA === fileB; };
|
var compareFiles = function (fileA, fileB) { return fileA === fileB; };
|
||||||
|
|
||||||
|
var isSharedFolder = exp.isSharedFolder = function (element) {
|
||||||
|
if (sharedFolder) { return false; } // No recursive shared folders
|
||||||
|
return Boolean(files[SHARED_FOLDERS] && files[SHARED_FOLDERS][element]);
|
||||||
|
};
|
||||||
var isFile = exp.isFile = function (element, allowStr) {
|
var isFile = exp.isFile = function (element, allowStr) {
|
||||||
|
if (isSharedFolder(element)) { return false; }
|
||||||
return typeof(element) === "number" ||
|
return typeof(element) === "number" ||
|
||||||
((typeof(files[OLD_FILES_DATA]) !== "undefined" || allowStr)
|
((typeof(files[OLD_FILES_DATA]) !== "undefined" || allowStr)
|
||||||
&& typeof(element) === "string");
|
&& typeof(element) === "string");
|
||||||
@@ -85,15 +95,11 @@ define([
|
|||||||
exp.isReadOnlyFile = function (element) {
|
exp.isReadOnlyFile = function (element) {
|
||||||
if (!isFile(element)) { return false; }
|
if (!isFile(element)) { return false; }
|
||||||
var data = exp.getFileData(element);
|
var data = exp.getFileData(element);
|
||||||
var parsed = Hash.parsePadUrl(data.href);
|
return Boolean(data.roHref && !data.href);
|
||||||
if (!parsed) { return false; }
|
|
||||||
var pHash = parsed.hashData;
|
|
||||||
if (!pHash || pHash.type !== "pad") { return; }
|
|
||||||
return pHash && pHash.mode === 'view';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var isFolder = exp.isFolder = function (element) {
|
var isFolder = exp.isFolder = function (element) {
|
||||||
return typeof(element) === "object";
|
return typeof(element) === "object" || isSharedFolder(element);
|
||||||
};
|
};
|
||||||
exp.isFolderEmpty = function (element) {
|
exp.isFolderEmpty = function (element) {
|
||||||
if (!isFolder(element)) { return false; }
|
if (!isFolder(element)) { return false; }
|
||||||
@@ -144,9 +150,11 @@ define([
|
|||||||
|
|
||||||
// Data from filesData
|
// Data from filesData
|
||||||
var getTitle = exp.getTitle = function (file, type) {
|
var getTitle = exp.getTitle = function (file, type) {
|
||||||
if (workgroup) { debug("No titles in workgroups"); return; }
|
if (isSharedFolder(file)) {
|
||||||
|
return '??';
|
||||||
|
}
|
||||||
var data = getFileData(file);
|
var data = getFileData(file);
|
||||||
if (!file || !data || !data.href) {
|
if (!file || !data || !(data.href || data.roHref)) {
|
||||||
error("getTitle called with a non-existing file id: ", file, data);
|
error("getTitle called with a non-existing file id: ", file, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -216,14 +224,16 @@ define([
|
|||||||
|
|
||||||
// GET FILES
|
// GET FILES
|
||||||
|
|
||||||
var getFilesRecursively = function (root, arr) {
|
var getFilesRecursively = exp.getFilesRecursively = function (root, arr) {
|
||||||
|
arr = arr || [];
|
||||||
for (var e in root) {
|
for (var e in root) {
|
||||||
if (isFile(root[e])) {
|
if (isFile(root[e]) || isSharedFolder(root[e])) {
|
||||||
if(arr.indexOf(root[e]) === -1) { arr.push(root[e]); }
|
if(arr.indexOf(root[e]) === -1) { arr.push(root[e]); }
|
||||||
} else {
|
} else {
|
||||||
getFilesRecursively(root[e], arr);
|
getFilesRecursively(root[e], arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return arr;
|
||||||
};
|
};
|
||||||
var _getFiles = {};
|
var _getFiles = {};
|
||||||
_getFiles['array'] = function (cat) {
|
_getFiles['array'] = function (cat) {
|
||||||
@@ -235,6 +245,7 @@ define([
|
|||||||
});
|
});
|
||||||
_getFiles['hrefArray'] = function () {
|
_getFiles['hrefArray'] = function () {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
|
if (sharedFolder) { return ret; }
|
||||||
getHrefArray().forEach(function (c) {
|
getHrefArray().forEach(function (c) {
|
||||||
ret = ret.concat(_getFiles[c]());
|
ret = ret.concat(_getFiles[c]());
|
||||||
});
|
});
|
||||||
@@ -249,7 +260,7 @@ define([
|
|||||||
var root = files[TRASH];
|
var root = files[TRASH];
|
||||||
var ret = [];
|
var ret = [];
|
||||||
var addFiles = function (el) {
|
var addFiles = function (el) {
|
||||||
if (isFile(el.element)) {
|
if (isFile(el.element) || isSharedFolder(el.element)) {
|
||||||
if(ret.indexOf(el.element) === -1) { ret.push(el.element); }
|
if(ret.indexOf(el.element) === -1) { ret.push(el.element); }
|
||||||
} else {
|
} else {
|
||||||
getFilesRecursively(el.element, ret);
|
getFilesRecursively(el.element, ret);
|
||||||
@@ -279,10 +290,15 @@ define([
|
|||||||
if (!files[FILES_DATA]) { return ret; }
|
if (!files[FILES_DATA]) { return ret; }
|
||||||
return Object.keys(files[FILES_DATA]).map(Number);
|
return Object.keys(files[FILES_DATA]).map(Number);
|
||||||
};
|
};
|
||||||
|
_getFiles[SHARED_FOLDERS] = function () {
|
||||||
|
var ret = [];
|
||||||
|
if (!files[SHARED_FOLDERS]) { return ret; }
|
||||||
|
return Object.keys(files[SHARED_FOLDERS]).map(Number);
|
||||||
|
};
|
||||||
var getFiles = exp.getFiles = function (categories) {
|
var getFiles = exp.getFiles = function (categories) {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
if (!categories || !categories.length) {
|
if (!categories || !categories.length) {
|
||||||
categories = [ROOT, 'hrefArray', TRASH, OLD_FILES_DATA, FILES_DATA];
|
categories = [ROOT, 'hrefArray', TRASH, OLD_FILES_DATA, FILES_DATA, SHARED_FOLDERS];
|
||||||
}
|
}
|
||||||
categories.forEach(function (c) {
|
categories.forEach(function (c) {
|
||||||
if (typeof _getFiles[c] === "function") {
|
if (typeof _getFiles[c] === "function") {
|
||||||
@@ -295,11 +311,11 @@ define([
|
|||||||
var getIdFromHref = exp.getIdFromHref = function (href) {
|
var getIdFromHref = exp.getIdFromHref = function (href) {
|
||||||
var result;
|
var result;
|
||||||
getFiles([FILES_DATA]).some(function (id) {
|
getFiles([FILES_DATA]).some(function (id) {
|
||||||
if (files[FILES_DATA][id].href === href) {
|
if (files[FILES_DATA][id].href === href ||
|
||||||
|
files[FILES_DATA][id].roHref === href) {
|
||||||
result = id;
|
result = id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -315,7 +331,7 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isFile(root)) {
|
if (isFile(root) || isSharedFolder(root)) {
|
||||||
if (compareFiles(file, root)) {
|
if (compareFiles(file, root)) {
|
||||||
if (paths.indexOf(path) === -1) {
|
if (paths.indexOf(path) === -1) {
|
||||||
paths.push(path);
|
paths.push(path);
|
||||||
@@ -335,6 +351,7 @@ define([
|
|||||||
return _findFileInRoot([ROOT], file);
|
return _findFileInRoot([ROOT], file);
|
||||||
};
|
};
|
||||||
var _findFileInHrefArray = function (rootName, file) {
|
var _findFileInHrefArray = function (rootName, file) {
|
||||||
|
if (sharedFolder) { return []; }
|
||||||
if (!files[rootName]) { return []; }
|
if (!files[rootName]) { return []; }
|
||||||
var unsorted = files[rootName].slice();
|
var unsorted = files[rootName].slice();
|
||||||
var ret = [];
|
var ret = [];
|
||||||
@@ -345,6 +362,7 @@ define([
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
var _findFileInTrash = function (path, file) {
|
var _findFileInTrash = function (path, file) {
|
||||||
|
if (sharedFolder) { return []; }
|
||||||
var root = find(path);
|
var root = find(path);
|
||||||
var paths = [];
|
var paths = [];
|
||||||
var addPaths = function (p) {
|
var addPaths = function (p) {
|
||||||
@@ -561,29 +579,29 @@ define([
|
|||||||
// DELETE
|
// DELETE
|
||||||
// Permanently delete multiple files at once using a list of paths
|
// Permanently delete multiple files at once using a list of paths
|
||||||
// NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template)
|
// NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template)
|
||||||
exp.delete = function (paths, cb, nocheck, isOwnPadRemoved) {
|
exp.delete = function (paths, cb, nocheck) {
|
||||||
if (sframeChan) {
|
if (sframeChan) {
|
||||||
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||||
cmd: "delete",
|
cmd: "delete",
|
||||||
data: {
|
data: {
|
||||||
paths: paths,
|
paths: paths,
|
||||||
nocheck: nocheck,
|
nocheck: nocheck,
|
||||||
isOwnPadRemoved: isOwnPadRemoved
|
|
||||||
}
|
}
|
||||||
}, cb);
|
}, cb);
|
||||||
}
|
}
|
||||||
exp.deleteMultiplePermanently(paths, nocheck, isOwnPadRemoved);
|
cb = cb || function () {};
|
||||||
if (typeof cb === "function") { cb(); }
|
exp.deleteMultiplePermanently(paths, nocheck, cb);
|
||||||
|
//if (typeof cb === "function") { cb(); }
|
||||||
};
|
};
|
||||||
exp.emptyTrash = function (cb) {
|
exp.emptyTrash = function (cb) {
|
||||||
|
cb = cb || function () {};
|
||||||
if (sframeChan) {
|
if (sframeChan) {
|
||||||
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
return void sframeChan.query("Q_DRIVE_USEROBJECT", {
|
||||||
cmd: "emptyTrash"
|
cmd: "emptyTrash"
|
||||||
}, cb);
|
}, cb);
|
||||||
}
|
}
|
||||||
files[TRASH] = {};
|
files[TRASH] = {};
|
||||||
exp.checkDeletedFiles();
|
exp.checkDeletedFiles(cb);
|
||||||
if(cb) { cb(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// RENAME
|
// RENAME
|
||||||
@@ -605,7 +623,7 @@ define([
|
|||||||
var element = find(path);
|
var element = find(path);
|
||||||
|
|
||||||
// Folders
|
// Folders
|
||||||
if (isFolder(element)) {
|
if (isFolder(element) && !isSharedFolder(element)) {
|
||||||
var parentPath = path.slice();
|
var parentPath = path.slice();
|
||||||
var oldName = parentPath.pop();
|
var oldName = parentPath.pop();
|
||||||
if (!newName || !newName.trim() || oldName === newName) { return; }
|
if (!newName || !newName.trim() || oldName === newName) { return; }
|
||||||
@@ -620,8 +638,13 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Files
|
// Files or Shared folder
|
||||||
var data = files[FILES_DATA][element];
|
var data;
|
||||||
|
if (isSharedFolder(element)) {
|
||||||
|
data = files[SHARED_FOLDERS][element];
|
||||||
|
} else {
|
||||||
|
data = files[FILES_DATA][element];
|
||||||
|
}
|
||||||
if (!data) { return; }
|
if (!data) { return; }
|
||||||
if (!newName || newName.trim() === "") {
|
if (!newName || newName.trim() === "") {
|
||||||
delete data.filename;
|
delete data.filename;
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
@import (once) "../../customize/src/less2/include/browser.less";
|
@import (reference) '../../customize/src/less2/include/avatar.less';
|
||||||
@import (once) "../../customize/src/less2/include/markdown.less";
|
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||||
@import (once) '../../customize/src/less2/include/avatar.less';
|
|
||||||
@import (once) '../../customize/src/less2/include/framework.less';
|
|
||||||
|
|
||||||
.framework_min_main(
|
|
||||||
@bg-color: @colortheme_friends-bg,
|
|
||||||
@warn-color: @colortheme_friends-warn,
|
|
||||||
@color: @colortheme_friends-color
|
|
||||||
);
|
|
||||||
|
|
||||||
// body
|
// body
|
||||||
&.cp-app-contacts {
|
&.cp-app-contacts {
|
||||||
|
.framework_min_main(
|
||||||
|
@bg-color: @colortheme_friends-bg,
|
||||||
|
@warn-color: @colortheme_friends-warn,
|
||||||
|
@color: @colortheme_friends-color
|
||||||
|
);
|
||||||
|
|
||||||
@keyframes example {
|
@keyframes example {
|
||||||
0% {
|
0% {
|
||||||
background: rgba(0,0,0,0.1);
|
background: rgba(0,0,0,0.1);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ define([
|
|||||||
|
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
'less!/customize/src/less2/main.less',
|
'less!/contacts/app-contacts.less',
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
Crypto,
|
Crypto,
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ define([
|
|||||||
|
|
||||||
// insert a newline if they're holding either
|
// insert a newline if they're holding either
|
||||||
var val = this.value;
|
var val = this.value;
|
||||||
var start = this.selectionState;
|
var start = this.selectionStart;
|
||||||
var end = this.selectionEnd;
|
var end = this.selectionEnd;
|
||||||
|
|
||||||
if (![start,end].some(function (x) {
|
if (![start,end].some(function (x) {
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
@import (once) "../../customize/src/less2/include/browser.less";
|
@import (reference) '../../customize/src/less2/include/tokenfield.less';
|
||||||
@import (once) "../../customize/src/less2/include/markdown.less";
|
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||||
@import (once) '../../customize/src/less2/include/tools.less';
|
|
||||||
@import (once) '../../customize/src/less2/include/tokenfield.less';
|
|
||||||
@import (once) '../../customize/src/less2/include/framework.less';
|
|
||||||
|
|
||||||
.tokenfield_main();
|
|
||||||
.framework_min_main();
|
|
||||||
|
|
||||||
// body
|
// body
|
||||||
&.cp-app-debug {
|
&.cp-app-debug {
|
||||||
|
.tokenfield_main();
|
||||||
|
.framework_min_main();
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ define([
|
|||||||
|
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
'less!/customize/src/less2/main.less',
|
'less!/debug/app-debug.less',
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
Crypto,
|
Crypto,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -37,10 +37,25 @@ define([
|
|||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var getSecrets = function (Cryptpad, Utils, cb) {
|
var getSecrets = function (Cryptpad, Utils, cb) {
|
||||||
var hash = window.location.hash.slice(1) || Utils.LocalStore.getUserHash() ||
|
var hash = window.location.hash.slice(1);
|
||||||
Utils.LocalStore.getFSHash();
|
var secret = Utils.Hash.getSecrets('drive', hash);
|
||||||
|
if (hash) {
|
||||||
|
// Add a shared folder!
|
||||||
|
// XXX password?
|
||||||
|
Cryptpad.addSharedFolder(secret, function (id) {
|
||||||
|
window.CryptPad_newSharedFolder = id;
|
||||||
|
// Update the hash in the address bar
|
||||||
|
var ohc = window.onhashchange;
|
||||||
|
window.onhashchange = function () {};
|
||||||
|
window.location.hash = "";
|
||||||
|
window.onhashchange = ohc;
|
||||||
|
ohc({reset:true});
|
||||||
|
cb(null, secret);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
// No password for drive
|
// No password for drive
|
||||||
cb(null, Utils.Hash.getSecrets('drive', hash));
|
cb(null, secret);
|
||||||
};
|
};
|
||||||
var addRpc = function (sframeChan, Cryptpad, Utils) {
|
var addRpc = function (sframeChan, Cryptpad, Utils) {
|
||||||
sframeChan.on('EV_BURN_ANON_DRIVE', function () {
|
sframeChan.on('EV_BURN_ANON_DRIVE', function () {
|
||||||
@@ -52,7 +67,16 @@ define([
|
|||||||
sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) {
|
sframeChan.on('Q_DRIVE_USEROBJECT', function (data, cb) {
|
||||||
Cryptpad.userObjectCommand(data, cb);
|
Cryptpad.userObjectCommand(data, cb);
|
||||||
});
|
});
|
||||||
|
sframeChan.on('Q_DRIVE_RESTORE', function (data, cb) {
|
||||||
|
Cryptpad.restoreDrive(data, cb);
|
||||||
|
});
|
||||||
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {
|
sframeChan.on('Q_DRIVE_GETOBJECT', function (data, cb) {
|
||||||
|
if (data && data.sharedFolder) {
|
||||||
|
Cryptpad.getSharedFolder(data.sharedFolder, function (obj) {
|
||||||
|
cb(obj);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
Cryptpad.getUserObject(function (obj) {
|
Cryptpad.getUserObject(function (obj) {
|
||||||
cb(obj);
|
cb(obj);
|
||||||
});
|
});
|
||||||
@@ -82,8 +106,10 @@ define([
|
|||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
getSecrets: getSecrets,
|
getSecrets: getSecrets,
|
||||||
noHash: true,
|
noHash: true,
|
||||||
|
noRealtime: true,
|
||||||
driveEvents: true,
|
driveEvents: true,
|
||||||
addRpc: addRpc
|
addRpc: addRpc,
|
||||||
|
isDrive: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ define([
|
|||||||
|
|
||||||
module.test = function (assert) {
|
module.test = function (assert) {
|
||||||
var config = {
|
var config = {
|
||||||
pinPads: Cryptpad.pinPads,
|
outer: true,
|
||||||
workgroup: false,
|
workgroup: false,
|
||||||
testMode: true,
|
testMode: true,
|
||||||
loggedIn: false
|
loggedIn: false
|
||||||
@@ -237,7 +237,8 @@ define([
|
|||||||
&& typeof files.template[0] === "number"
|
&& typeof files.template[0] === "number"
|
||||||
&& typeof files.filesData[files.template[0]] === "object"
|
&& typeof files.filesData[files.template[0]] === "object"
|
||||||
&& !files.filesData[files.template[0]].filename
|
&& !files.filesData[files.template[0]].filename
|
||||||
&& files.filesData[files.template[0]].href === href3
|
&& !files.filesData[files.template[0]].href
|
||||||
|
&& files.filesData[files.template[0]].roHref === href3
|
||||||
&& typeof fileId2 === "number"
|
&& typeof fileId2 === "number"
|
||||||
&& typeof files.filesData[fileId2] === "object"
|
&& typeof files.filesData[fileId2] === "object"
|
||||||
&& files.filesData[fileId2].filename === "Trash"
|
&& files.filesData[fileId2].filename === "Trash"
|
||||||
@@ -392,11 +393,6 @@ define([
|
|||||||
console.log("DRIVE operations: rename");
|
console.log("DRIVE operations: rename");
|
||||||
return cb();
|
return cb();
|
||||||
}
|
}
|
||||||
fo.replace(href1, href2);
|
|
||||||
if (fo.getFileData(id1).href !== href2) {
|
|
||||||
console.log("DRIVE operations: replace");
|
|
||||||
return cb();
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(true);
|
cb(true);
|
||||||
}, "DRIVE operations");
|
}, "DRIVE operations");
|
||||||
|
|||||||
@@ -1,151 +1,152 @@
|
|||||||
@import (once) "../../customize/src/less2/include/browser.less";
|
@import (reference) '../../customize/src/less2/include/tokenfield.less';
|
||||||
@import (once) "../../customize/src/less2/include/markdown.less";
|
@import (reference) '../../customize/src/less2/include/framework.less';
|
||||||
@import (once) '../../customize/src/less2/include/tokenfield.less';
|
|
||||||
@import (once) '../../customize/src/less2/include/framework.less';
|
|
||||||
|
|
||||||
.framework_min_main(
|
&.cp-app-file {
|
||||||
@bg-color: @colortheme_file-bg,
|
|
||||||
@warn-color: @colortheme_file-warn,
|
|
||||||
@color: @colortheme_file-color
|
|
||||||
);
|
|
||||||
.tokenfield_main();
|
|
||||||
|
|
||||||
@button-border: 2px;
|
.framework_min_main(
|
||||||
|
@bg-color: @colortheme_file-bg,
|
||||||
|
@warn-color: @colortheme_file-warn,
|
||||||
|
@color: @colortheme_file-color
|
||||||
|
);
|
||||||
|
.tokenfield_main();
|
||||||
|
|
||||||
// body
|
@button-border: 2px;
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
|
|
||||||
#cp-app-file-content {
|
// body
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cp-app-file-content.ready {
|
#cp-app-file-content {
|
||||||
//background: url('/customize/bg3.jpg') no-repeat center center;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cp-app-file-upfile, #cp-app-file-dlfile {
|
|
||||||
display: block;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
border: @button-border solid black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-app-file-input {
|
|
||||||
width: 0.1px;
|
|
||||||
height: 0.1px;
|
|
||||||
opacity: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
media-tag {
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: ~"calc(100vh - 96px)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#cp-app-file-upload-form, #cp-app-file-download-form {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
width: 50vh;
|
|
||||||
height: 50vh;
|
|
||||||
display: block;
|
|
||||||
margin: 50px auto;
|
|
||||||
max-width: 80vw;
|
|
||||||
label {
|
|
||||||
line-height: ~"calc(50vh - 20px)";
|
|
||||||
text-align: center;
|
|
||||||
position: relative;
|
|
||||||
padding: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
height: 50vh;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#cp-app-file-download-form {
|
|
||||||
label {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
white-space: normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
span {
|
|
||||||
width: 50vh;
|
|
||||||
max-width: 80vw;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.cp-app-file-hovering {
|
|
||||||
background-color: rgba(255, 0, 115, 0.5) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-app-file-block {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.cp-app-file-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.cp-app-file-input + label {
|
|
||||||
//border: 2px solid black;
|
|
||||||
//background-color: rgba(50, 50, 50, .10);
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cp-app-file-input:focus + label,
|
|
||||||
.cp-app-file-input + label:hover {
|
|
||||||
//background-color: rgba(50, 50, 50, 0.30);
|
|
||||||
}
|
|
||||||
|
|
||||||
#cp-app-file-dlprogress {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
|
|
||||||
transition: width 200ms;
|
|
||||||
width: 0%;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
background-color: rgba(255, 0, 115, 0.75);
|
|
||||||
z-index: 10000;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#cp-app-file-download-view {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
min-height: 0;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-flow: column;
|
|
||||||
media-tag {
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
|
||||||
max-width: 100vw;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
&> * {
|
align-items: center;
|
||||||
max-height: 100%;
|
flex-flow: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-app-file-content.ready {
|
||||||
|
//background: url('/customize/bg3.jpg') no-repeat center center;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-app-file-upfile, #cp-app-file-dlfile {
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border: @button-border solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-app-file-input {
|
||||||
|
width: 0.1px;
|
||||||
|
height: 0.1px;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
media-tag {
|
||||||
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
max-height: ~"calc(100vh - 96px)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cp-app-file-upload-form, #cp-app-file-download-form {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
width: 50vh;
|
||||||
|
height: 50vh;
|
||||||
|
display: block;
|
||||||
|
margin: 50px auto;
|
||||||
|
max-width: 80vw;
|
||||||
|
label {
|
||||||
|
line-height: ~"calc(50vh - 20px)";
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
padding: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
height: 50vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#cp-app-file-download-form {
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
white-space: normal;
|
||||||
|
word-wrap: break-word;
|
||||||
|
span {
|
||||||
|
width: 50vh;
|
||||||
|
max-width: 80vw;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cp-app-file-hovering {
|
||||||
|
background-color: rgba(255, 0, 115, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-app-file-block {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.cp-app-file-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.cp-app-file-input + label {
|
||||||
|
//border: 2px solid black;
|
||||||
|
//background-color: rgba(50, 50, 50, .10);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-app-file-input:focus + label,
|
||||||
|
.cp-app-file-input + label:hover {
|
||||||
|
//background-color: rgba(50, 50, 50, 0.30);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-app-file-dlprogress {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
transition: width 200ms;
|
||||||
|
width: 0%;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
background-color: rgba(255, 0, 115, 0.75);
|
||||||
|
z-index: 10000;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-app-file-download-view {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
min-height: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-flow: column;
|
||||||
|
media-tag {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
max-width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
&> * {
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ define([
|
|||||||
var increment = function (N) {
|
var increment = function (N) {
|
||||||
var l = N.length;
|
var l = N.length;
|
||||||
while (l-- > 1) {
|
while (l-- > 1) {
|
||||||
/* jshint probably suspects this is unsafe because we lack types
|
/* our linter suspects this is unsafe because we lack types
|
||||||
but as long as this is only used on nonces, it should be safe */
|
but as long as this is only used on nonces, it should be safe */
|
||||||
if (N[l] !== 255) { return void N[l]++; } // jshint ignore:line
|
if (N[l] !== 255) { return void N[l]++; } // jshint ignore:line
|
||||||
if (l === 0) { throw new Error('E_NONCE_TOO_LARGE'); }
|
if (l === 0) { throw new Error('E_NONCE_TOO_LARGE'); }
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ define([
|
|||||||
|
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
'less!/customize/src/less2/main.less',
|
'less!/file/app-file.less',
|
||||||
|
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
|
|||||||
@@ -1,83 +1,85 @@
|
|||||||
@import (once) '../../customize/src/less2/include/colortheme-all.less';
|
@import (reference) '../../customize/src/less2/include/colortheme-all.less';
|
||||||
@import (once) '../../customize/src/less2/include/modal.less';
|
@import (reference) '../../customize/src/less2/include/modal.less';
|
||||||
@import (once) '../../customize/src/less2/include/icon-colors.less';
|
@import (reference) '../../customize/src/less2/include/icon-colors.less';
|
||||||
@import (once) '../../customize/src/less2/include/fileupload.less';
|
@import (reference) '../../customize/src/less2/include/fileupload.less';
|
||||||
@import (once) '../../customize/src/less2/include/alertify.less';
|
@import (reference) '../../customize/src/less2/include/alertify.less';
|
||||||
@import (once) '../../customize/src/less2/include/tippy.less';
|
@import (reference) '../../customize/src/less2/include/tippy.less';
|
||||||
@import (once) '../../customize/src/less2/include/checkmark.less';
|
@import (reference) '../../customize/src/less2/include/checkmark.less';
|
||||||
@import (once) '../../customize/src/less2/include/password-input.less';
|
@import (reference) '../../customize/src/less2/include/password-input.less';
|
||||||
|
|
||||||
.iconColors_main();
|
&.cp-app-filepicker {
|
||||||
.fileupload_main();
|
.iconColors_main();
|
||||||
.alertify_main();
|
.fileupload_main();
|
||||||
.tippy_main();
|
.alertify_main();
|
||||||
.checkmark_main(20px);
|
.tippy_main();
|
||||||
.password_main();
|
.checkmark_main(20px);
|
||||||
|
.password_main();
|
||||||
|
.modal_main();
|
||||||
|
|
||||||
#cp-filepicker-dialog {
|
#cp-filepicker-dialog {
|
||||||
display: none;
|
display: none;
|
||||||
.cp-modal {
|
.cp-modal {
|
||||||
.cp-filepicker-content {
|
.cp-filepicker-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.cp-filepicker-content-element {
|
|
||||||
@darker: darken(@colortheme_modal-fg, 30%);
|
|
||||||
|
|
||||||
width: 125px;
|
|
||||||
//min-width: 200px;
|
|
||||||
//height: 1em;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 5px;
|
|
||||||
|
|
||||||
display: inline-flex;
|
|
||||||
flex-flow: column;
|
|
||||||
|
|
||||||
box-sizing: content-box;
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
line-height: 1em;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
background-color: @colortheme_modal-bg;
|
|
||||||
box-shadow: 2px 2px 5px #000;
|
|
||||||
color: @darker;
|
|
||||||
|
|
||||||
transition: all 0.1s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: @colortheme_modal-fg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
align-items: center;
|
.cp-filepicker-content-element {
|
||||||
|
@darker: darken(@colortheme_modal-fg, 30%);
|
||||||
|
|
||||||
img {
|
width: 125px;
|
||||||
max-width: 100px;
|
//min-width: 200px;
|
||||||
max-height: 100px;
|
//height: 1em;
|
||||||
background: #fff;
|
padding: 10px;
|
||||||
}
|
margin: 5px;
|
||||||
|
|
||||||
.cp-filepicker-content-element-name {
|
display: inline-flex;
|
||||||
overflow: hidden;
|
flex-flow: column;
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
box-sizing: content-box;
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
text-align: left;
|
||||||
margin-top: 5px;
|
line-height: 1em;
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
.fa {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
background-color: @colortheme_modal-bg;
|
||||||
font-size: 70px;
|
box-shadow: 2px 2px 5px #000;
|
||||||
text-align: center;
|
color: @darker;
|
||||||
line-height: 100px;
|
|
||||||
|
transition: all 0.1s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: @colortheme_modal-fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100px;
|
||||||
|
max-height: 100px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-filepicker-content-element-name {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-top: 5px;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
.fa {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
font-size: 70px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ define([
|
|||||||
|
|
||||||
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
'less!/customize/src/less2/main.less',
|
'less!/filepicker/app-filepicker.less',
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
Crypto,
|
Crypto,
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
@import (once) "../../customize/src/less2/include/browser.less";
|
@import (reference) "../../customize/src/less2/include/browser.less";
|
||||||
@import (once) "../../customize/src/less2/include/framework.less";
|
@import (reference) "../../customize/src/less2/include/framework.less";
|
||||||
@import (once) "../../customize/src/less2/include/tools.less";
|
@import (reference) "../../customize/src/less2/include/tools.less";
|
||||||
|
|
||||||
.framework_main( @bg-color: @colortheme_kanban-bg,
|
|
||||||
@warn-color: @colortheme_kanban-warn,
|
|
||||||
@color: @colortheme_kanban-color);
|
|
||||||
|
|
||||||
// body
|
// body
|
||||||
&.cp-app-kanban {
|
&.cp-app-kanban {
|
||||||
|
.framework_main(
|
||||||
|
@bg-color: @colortheme_kanban-bg,
|
||||||
|
@warn-color: @colortheme_kanban-warn,
|
||||||
|
@color: @colortheme_kanban-color
|
||||||
|
);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ define([
|
|||||||
'/kanban/jkanban.js',
|
'/kanban/jkanban.js',
|
||||||
'/kanban/jscolor.js',
|
'/kanban/jscolor.js',
|
||||||
'css!/kanban/jkanban.css',
|
'css!/kanban/jkanban.css',
|
||||||
|
|
||||||
|
'less!/kanban/app-kanban.less'
|
||||||
], function (
|
], function (
|
||||||
$,
|
$,
|
||||||
Sortify,
|
Sortify,
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user