diff --git a/.flowconfig b/.flowconfig index 280ef23f8..1c97394ee 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,5 +1,6 @@ [ignore] .*/bower_components/.* +.*/node_modules/lesshint/* [include] [libs] diff --git a/.lesshintrc b/.lesshintrc new file mode 100644 index 000000000..693029bf1 --- /dev/null +++ b/.lesshintrc @@ -0,0 +1,60 @@ +{ + "fileExtensions": [".less"], + + // These rules are almost certainly crap and will not catch bugs (Caleb) + "newlineAfterBlock": { "enabled": false }, // not just a newline but an entire empty line after each block + "spaceAroundOperator": { "enabled": false }, // disallow calc(10px+10px); + "hexLength": { "enabled": false }, // require long hex color codes or require short where possible + "hexNotation": { "enabled": false }, // require hex lowercase + "propertyOrdering": { "enabled": false }, // require attributes to be in alphabetical order D: + "stringQuotes": { "enabled": false }, // force quoting of strings with ' or " (silly) + "importPath": { "enabled": false }, // require imports to not have .less, ridiculous + "qualifyingElement": { "enabled": false }, // disallow div.xxx and require .xxx + "decimalZero": { "enabled": false }, // disallow .5em + "borderZero": { "enabled": false }, // disallow border: none; + "selectorNaming": { "enabled": false }, // this would be crap because classes are what they are. + "zeroUnit": { "enabled": false }, + "singleLinePerProperty": { "enabled": false }, + "_singleLinePerProperty": { + "enabled": true, + "allowSingleLineRules": true + }, + "spaceAroundComma": { "enabled": false }, + "importantRule": { "enabled": false }, + "universalSelector": { "enabled": false }, + "idSelector": { "enabled": false }, + "singleLinePerSelector": { "enabled": false }, + "spaceBetweenParens": { "enabled": false }, + "maxCharPerLine": { "enabled": false }, // using lesshint flags can cause long lines + "comment": { "enabled": false }, // ban multi-line comments ? + + // These rules should be discussed, if they're crap then they should be moved up. + "colorVariables": { "enabled": false }, // require all colors to be stored as variables first... + "variableValue": { "enabled": false }, // any attribute types which should always be variables ? color? + "spaceBeforeBrace": { "enabled": true },//{ "enabled": true, "style": "one_space" }, + + // Turn everything else on + "spaceAfterPropertyColon": { "enabled": true }, + "finalNewline": { "enabled": true }, // require an empty line at the end of the file (enabled for now) + "attributeQuotes": { "enabled": true }, + "depthLevel": { + "depth": 1 // TODO(cjd) This is obviously not triggering, even with 1 + }, + "duplicateProperty": { "enabled": true }, + "emptyRule": { "enabled": true }, + "hexValidation": { "enabled": true }, // disallow actual garbage color hex codes (e.g. #ab) + "propertyUnits": { + "valid": ["rem", "vw", "em", "px"], // These units are allowed for all properties + "invalid": ["pt"], // The 'pt' unit is not allowed under any circumstances + "properties": { + //"line-height": [] // No units are allowed for line-height + } + }, + "spaceAfterPropertyName": { "enabled": true, "style": "no_space" }, + "spaceAfterPropertyValue": { "enabled": true, "style": "no_space" }, + "spaceAroundBang": { "enabled": true, "style": "before" }, + "trailingSemicolon": { "enabled": true }, + "trailingWhitespace": { "enabled": true }, + "urlFormat": { "enabled": true, "style": "relative" }, + "urlQuotes": { "enabled": true } +} diff --git a/.travis.yml b/.travis.yml index 9fe64ca63..d77e49fa1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,4 @@ language: node_js -env: - matrix: - - "BROWSER='firefox::Windows 10'" - - "BROWSER='chrome::Windows 10'" - #- "BROWSER='MicrosoftEdge:14.14393:Windows 10'" - #- "BROWSER='internet explorer:11.103:Windows 10'" - #- "BROWSER='safari:10.0:macOS 10.12'" - #- "BROWSER='safari:9.0:OS X 10.11'" branches: only: - master @@ -14,16 +6,6 @@ branches: - staging node_js: - "6.6.0" -before_script: +script: - npm run-script lint - npm run-script flow - - cp config.example.js config.js - - npm install bower - - ./node_modules/bower/bin/bower install - - node ./server.js & - - sleep 2 -addons: - sauce_connect: - username: "cjdelisle" - access_key: - secure: "pgGh8YGXLPq6fpdwwK2jnjRtwXPbVWQ/HIFvwX7E6HBpzxxcF2edE8sCdonWW9TP2LQisZFmVLqoSnZWMnjBr2CBAMKMFvaHQDJDQCo4v3BXkID7KgqyKmNcwW+FPfSJ5MxNBro8/GE/awkhZzJLYGUTS5zi/gVuIUwdi6cHI8s=" diff --git a/config.example.js b/config.example.js index 3a097eb87..6d1104497 100644 --- a/config.example.js +++ b/config.example.js @@ -169,10 +169,15 @@ module.exports = { */ customLimits: { /* - "https://my.awesome.website/user/#/1/cryptpad-user/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=": { + "https://my.awesome.website/user/#/1/cryptpad-user1/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=": { limit: 20 * 1024 * 1024 * 1024, plan: 'insider', note: 'storage space donated by my.awesome.website' + }, + "https://my.awesome.website/user/#/1/cryptpad-user2/GdflkgdlkjeworijfkldfsdflkjeEAsdlEnkbx1vVOo=": { + limit: 10 * 1024 * 1024 * 1024, + plan: 'insider', + note: 'storage space donated by my.awesome.website' } */ }, diff --git a/customize.dist/application_config.js b/customize.dist/application_config.js index 079c36eab..3fc4097d1 100644 --- a/customize.dist/application_config.js +++ b/customize.dist/application_config.js @@ -65,5 +65,7 @@ define(function() { contacts: 'fa-users', }; + config.displayCreationScreen = false; + return config; }); diff --git a/customize.dist/messages.js b/customize.dist/messages.js index 7e84dd01d..806141c8b 100644 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -93,7 +93,11 @@ define(req, function(Util, Default, Language) { var text = messages[key]; if (typeof(text) === 'string') { return text.replace(/\{(\d+)\}/g, function (str, p1) { - return argArray[p1] || null; + if (typeof(argArray[p1]) === 'string' || typeof(argArray[p1]) === "number") { + return argArray[p1]; + } + console.error("Only strings and numbers can be used in _getKey params!"); + return ''; }); } else { return text; diff --git a/customize.dist/pages.js b/customize.dist/pages.js index 6868418cc..510725a8b 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -71,7 +71,7 @@ define([ ]) ]) ]), - h('div.cp-version-footer', "CryptPad v1.21.0 (Vampire)") + h('div.cp-version-footer', "CryptPad v1.22.0 (Wendigo)") ]); }; diff --git a/customize.dist/src/less/bar.less b/customize.dist/src/less/bar.less deleted file mode 100644 index 91744728b..000000000 --- a/customize.dist/src/less/bar.less +++ /dev/null @@ -1,92 +0,0 @@ -/* Bottom Bar */ -@import (once) "../less2/include/colortheme.less"; - -.top-bar, .bottom-bar { - position:fixed; - height:4%; - height: 2.5em; - - display: inline-block; - width: 100%; - background: @base; - border-top: 1px solid @cp-outline; - - a { - color: @cp-green; - text-decoration: none; - } - p { - margin: -1px; - font-family: @colortheme_font; - - font-size: 20px; - display:block; - margin-left: 10px; - padding-top:3px; - color: @fore; - } - img { - margin-right: 4px; - position: relative; - } - - .big { - @media screen and (max-width: @media-not-big) { - display: none; - } - @media screen and (min-width: @media-not-small) { - display: inline-block; - } - } - .small { - @media screen and (max-width: @media-not-big) { - display: inline-block; - } - @media screen and (min-width: @media-not-small) { - display: none; - } - img { - height: 1.25em; - } - } - -} -.bottom-bar { - bottom: 0px; - right: 0px; -} -.top-bar { - top: 0px; - right: 0px; -} - -.bottom-bar-left { - display:block; - float:left; - padding-left:10px; -} -.bottom-bar-left p { - float: right; -} -.bottom-bar-right { - display:block; - float:right; - padding-right:20px -} -.bottom-bar-center { - width: 20%; - position: absolute; - left: 40%; - text-align: center; -} -.bottom-bar-heart { - top: 2px; -} -.bottom-bar-xwiki { - top: 3px; -} -.bottom-bar-openpaas { - top: 3px; - max-width: 100px; -} - diff --git a/customize.dist/src/less/cryptpad.less b/customize.dist/src/less/cryptpad.less deleted file mode 100644 index 12168ec88..000000000 --- a/customize.dist/src/less/cryptpad.less +++ /dev/null @@ -1,689 +0,0 @@ -@import "./variables.less"; -@import "./mixins.less"; - -@import "../less2/include/alertify.less"; -@import "../less2/include/colortheme.less"; -@import "../less2/include/modal.less"; -@import "../less2/include/font.less"; -@import "../less2/loading.less"; -@import "./bar.less"; -@import "./dropdown.less"; -@import "./topbar.less"; -@import "./footer.less"; - -@toolbar-green: #5cb85c; - -.font_open-sans(); - -.alertify_main(); - -html.cp, .cp body { - font-size: .875em; - background-color: @page-white; //@base; - color: @fore; - - height: 100%; -} -.fa { - cursor: default; // Fix for Edge displaying the text cursor on every icon -} - -.cp { - -// add font for tooltips -.tippy-popper { - font: 16px @colortheme_font; -} - -// override bootstrap colors -.btn-primary { - background-color: @cp-blue; - &:hover { - color: #fff; - background-color: #025aa5; - border-color: #01549b; - } -} - -body { - font-size: 1rem; - font-weight: 400; - line-height: 2rem; - margin: 0; -} - -a.github-corner > svg { - fill: @cp-blue; - color: @old-base; -} - -.lato { - font-family: lato, Helvetica, sans-serif; - font-size: 1.02em; -} - -.unselectable { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -h1,h2,h3,h4,h5,h6 { - color: @fore; - - font-family: @colortheme_font; - -webkit-font-feature-settings: 'dlig' 1,'liga' 1,'lnum' 1,'kern' 1; - -moz-font-feature-settings: 'dlig' 1,'liga' 1,'lnum' 1,'kern' 1; - font-feature-settings: 'dlig' 1,'liga' 1,'lnum' 1,'kern' 1; - font-style: normal; - font-weight: 600; - margin-top: 0; -} - -h1 { - line-height: 3rem; - font-size: 2.05714rem; - margin-bottom: .21999rem; - padding-top: .78001rem; -} - -h2 { - font-size: 1.95312rem; - margin-bottom: .18358rem; - padding-top: .81642rem; -} - -h2,h3 { - line-height: 3rem; -} - -h3 { - font-size: 1.64571rem; - margin-bottom: .07599rem; - padding-top: .92401rem; -} - -h4 { - font-size: 1.5625rem; - margin-bottom: .54686rem; - padding-top: .45314rem; -} - -h5 { - font-size: 1.25rem; - margin-bottom: -.56251rem; - padding-top: .56251rem; -} - -h6 { - font-size: 1rem; - margin-bottom: -.65001rem; - padding-top: .65001rem; -} - -p { - a:not(.btn) { - cursor: pointer; - color: @cp-link; - - text-decoration: none; - - &:hover { - color: @cp-link-hover; - } - &:visited { - color: @cp-link-visited; - } - } -} -a.btn { - font-family: sans-serif; -} - -img { - height: auto; - max-width: 100%; -} - -p { - padding-top: .66001rem; - margin-top: 0; -} - -p,pre { - margin-bottom: 1.33999rem; -} - -p, pre, td, a, table, tr { - .lato; -} - -body.html { - display:flex; - flex-flow: column; -} - -// Main page -.page { - width: 100%; - margin-left: auto; - margin-right: auto; - background: @page-white; - padding: 10px 0;//@main-border-width; - position: relative; - - .info-container { - color: #121212; - width: 800px; - max-width: 100%; - margin: 0 auto; - &>div{ - padding: 10px; - width: 400px; - max-width: 100%; - position: relative; - display: inline-block; - vertical-align: middle; - &:not(.image) { - @media screen and (max-width: @media-not-big) { - width: 100%; - left: 0; - } - } - &.image { - width:300px; - text-align: center; - @media screen and (max-width: @media-not-big) { - display: none; - } - } - } - } - - &.first { - //margin-top: ~"min(calc(100vh - 150px), 650px)"; - @media screen and (max-width: @media-not-big) { - //margin-top: 0; - } - } - &.even { - //background: darken(@base, 1%); - } - &.category { - background: @category-bg; - } - - .app { - display: inline-block; - width: 300px; - vertical-align: middle; - margin: 0px 25px; - white-space: normal; - max-width: ~"calc(50% - 50px)"; - @media screen and (max-width: 500px) { - display: block; - max-width: 100%; - margin: 0 auto; - } - } - .app-container { - width: 1400px; - max-width: 100%; - margin: 0 auto; - } - .app-row { - display: flex; - justify-content: center; - flex-flow: row wrap; - max-width: 100%; - margin: 0 auto; - @media screen and (max-width: 1399px) { - display: flex; - } - img { - @media screen and (max-width: @media-not-big) { - display: none; - } - } - } - - .left { - //left: 10%; //@main-border-width; - } - .right { - left: 100px; //@main-border-width; - } - - h1, h2, h3, h4, h5, h6 { - padding: 0; - } - - @media screen and (max-width: @media-not-big) { - padding: 10px 5vh; - } - - p { - font-size: 18px; - //text-align: justify; - } -} - -.btn-default { - &:hover { - background-color: #d8d8d8; - } -} - -#main { - .mainOverlay { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: #000; - opacity: 0.35; - } -} -noscript { - #noscriptContainer { - color: black; - position: absolute; - top: @topbar-height; - left: 0; - bottom: 0; - right: 0; - z-index: 2; // noscriptContainer - #noscript { - width: 1000px; - display: flex; - align-items: center; - justify-content: center; - height: 100%; - margin-left: auto; - margin-right: auto; - position: relative; - font-size: 25px; - text-align: center; - color: @main-color; - } - } -} -#main { - background: @main-bg; - background-size: cover; - background-attachment: fixed; - background-position: center; - height: ~"calc(100vh - 115px)"; - min-height: 450px; - .hidden { - display: none !important; - } -} -#main_other { - padding: 0 @main-border-width; - background-color: @page-white; -} - -.category { - margin-top: 5px; -} - -#mainBlock { - flex: 1; -} - -#main, #main_other { - position: relative; - left: 0; - right: 0; - margin: auto; - z-index: 1; // #main, #main_other - - font-size: medium; - - #align-container { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - margin-left: auto; - margin-right: auto; - width: 1000px; - max-width: 90%; - position: relative; - } - - #main-container { - display: inline-block; - } - - #userForm .extra { - p { - font-size: 28px; - padding: 15px; - text-align: center; - } - } - - #data { - p { - margin: 0; - padding: 0; - font-size: 28px; - line-height: 1.5em; - &.register-explanation { - font-size: 18px; - } - } - h1, h2 { - font-weight: normal; - font-size: 48px; - line-height: 1.2em; - color: @main-color; - padding: 0; - } - - h5 { - font-size: 1em; - color: @main-color; - } - width: 600px; - max-width: 60%; - color: @main-color; - padding: 0 15px; - box-sizing: border-box; - display: inline-block; - - #tryit { - margin-top: 20px; - margin-bottom: 5px; - } - } - - #loggedIn { - float: right; - color: @main-color; - display: inline-block; - width: 350px; - max-width: 35%; - text-align: center; - font-weight: bold; - button { - font-weight: bold; - cursor: pointer; - } - p { - margin: 20px; - padding: 0; - font-size: 20px; - line-height: 1.5em; - } - - } - - #userForm { - float: right; - display: inline-block; - width: 400px; - max-width: 40%; - padding: 10px; - box-sizing: border-box; - font-family: @colortheme_font; - color: @main-color; - - label { - margin-bottom: 0; - margin-left: 5px; - vertical-align: middle; - } - - button { - font-weight: bold; - width: 100%; - cursor: pointer; - &.half { - width: ~"calc(50% - 10px)"; - &:not(.first) { - float: right; - } - } - } - - p { - margin: 0; - padding: 0; - &.buttons { - margin-bottom: 10px; - .cp-dropdown-container { - button { - white-space: normal; - text-align: left; - .fa { - float: right; - } - } - a { - color: black; - &:hover, :visited { - color: black !important; - } - } - display: block; - } - } - &.separator { - margin: 5px 0 15px 0; - text-align: center; - font-weight: bold; - font-size: 1.1em; - } - a { - color: @main-color; - font-weight:bold; - font-size: 14px; - &:hover, :visited { - color: @main-color !important; - } - } - } - - .driveLink { - padding-left: 1rem; //Bootstrap padding in buttons - font-size: 1em; - } - - &> * { - margin-bottom: 10px; - } - } - @media screen and (max-width: @media-not-big) { - #align-container { - transform: initial; - position: relative; - display: block; - width: 90%; - left: 0; - } - #main-container { - position: relative; - transform: unset; - top:0; - - } - #data { - text-align: center; - } - #userForm, #loggedIn, #data { - transform: initial; - position: relative; - display: block; - width: 100%; - max-width: 100%; - margin: 10px 0; - box-sizing: border-box; - float: none; - } - #userForm, #loggedIn { - //border: 1px solid #888; - } - position: relative; - height: auto; - } - - .buttons { - margin-top: 15px; - } -} - -/* buttons */ - -.create, .action { - display: inline-block; - @thick: 2px; - border: 0; - background-color: @cp-darkblue; - color: @topbar-button-color; - - font-weight: bold; - font-size: large; - margin-right: 5px; - margin-left: 5px; - &:hover { - color: darken(@topbar-button-color, 20%); - } -} - -// currently only used in /user/ -.panel { - background-color: @dark-base; -} - -/* Tables - * Currently only used by /poll/ - */ - -// form things -.bottom-left { - .bottom-left; -} - -.top-left { - .top-left; -} - -.remove { - color: @cp-red; - cursor: pointer !important; -} -} - -/* Pin limit */ -.limit-container { - display: inline-flex; - flex-flow: column-reverse; - width: 100%; - margin-top: 20px; - .cryptpad-limit-bar { - display: inline-block; - max-width: 100%; - margin: 3px; - box-sizing: border-box; - border: 1px solid #999; - background: white; - position: relative; - text-align: center; - vertical-align: middle; - width: ~"calc(100% - 6px)"; - height: 25px; - line-height: 25px; - overflow: hidden; - .usage { - height: 100%; - display: inline-block; - background: blue; - position: absolute; - left: 0; - z-index:1; // .usage - &.normal { - background: @toolbar-green; - } - &.warning { - background: orange; - } - &.above { - background: red; - } - } - .usageText { - position: relative; - color: black; - text-shadow: 1px 0 2px white, 0 1px 2px white, -1px 0 2px white, 0 -1px 2px white; - z-index: 2; // .usageText - font-size: @main-font-size; - font-weight: bold; - } - } - .upgrade { - padding: 0; - line-height: 25px; - height: 25px; - margin: 0 3px; - border-radius: 0; - } -} - -/* Upload status table */ -#uploadStatusContainer { - .modal_base(); - position: absolute; - left: 10vw; right: 10vw; - bottom: 10vh; - opacity: 0.9; - box-sizing: border-box; - z-index: 10000; // #uploadStatusContainer - display: none; - #uploadStatus { - width: 80vw; - tr:nth-child(1) { - background-color: darken(@colortheme_modal-bg, 20%); - td { - text-align: center; - font-weight: bold; - padding: 0.25em; - } - } - @upload_pad_h: 0.25em; - @upload_pad_v: 0.5em; - - td { - padding: @upload_pad_h @upload_pad_v; - } - .upProgress { - width: 200px; - position: relative; - text-align: center; - box-sizing: border-box; - } - .progressContainer { - position: absolute; - width: 0px; - left: @upload_pad_v; - top: @upload_pad_h; bottom: @upload_pad_h; - background-color: rgba(0,0,255,0.3); - z-index: -1; // .progressContainer - } - .upCancel { text-align: center; } - .fa.cancel { - color: rgb(255, 0, 115); - } - } -} - -// hack for our cross-origin iframe -#cors-store { - display: none; -} diff --git a/customize.dist/src/less/dropdown.less b/customize.dist/src/less/dropdown.less deleted file mode 100644 index 47f06f88c..000000000 --- a/customize.dist/src/less/dropdown.less +++ /dev/null @@ -1,4 +0,0 @@ -@import (once) "../less2/include/dropdown.less"; - -.dropdown_main(); - diff --git a/customize.dist/src/less/footer.less b/customize.dist/src/less/footer.less deleted file mode 100644 index 97b5bda8c..000000000 --- a/customize.dist/src/less/footer.less +++ /dev/null @@ -1,30 +0,0 @@ -@import "./variables.less"; -@import (once) "../less2/include/colortheme.less"; - -footer { - background: @category-bg; - font-family: @colortheme_font; - padding-top: 1em; - font-size: 1.2em; - a { - color: @cp-link; - &:visited { - color: @cp-link-visited; - } - &:hover { - color: @cp-link-hover; - } - } - li.title { - font-size: 1.2em; - font-weight: bold; - } - div.version-footer { - background-color: @old-base; - color: @old-fore; - text-align: center; - width: 100%; - padding-top: 10px; - padding-bottom: 10px; - } -} diff --git a/customize.dist/src/less/mixins.less b/customize.dist/src/less/mixins.less deleted file mode 100644 index a75fa4e30..000000000 --- a/customize.dist/src/less/mixins.less +++ /dev/null @@ -1,193 +0,0 @@ -@import "/customize/src/less/variables.less"; -@import (once) "/customize/src/less2/include/tools.less"; - -.fontface(@family, @src, @style: normal, @weight: 400, @fmt: 'truetype'){ - @font-face { - font-family: @family; - src: url(@src) format(@fmt); - font-weight: @weight; - font-style: @style; - } -} - -.transform(...) { - -webkit-transform: @arguments; - -moz-transform: @arguments; - -o-transform: @arguments; - -ms-transform: @arguments; - transform: @arguments; -} - -.translate(@x:0, @y:0) { - .transform(translate(@x, @y)); -} - -.bottom-left(@s: 5px) { border-bottom-left-radius: @s; } -.top-left(@s: 5px) { border-top-left-radius: @s; } - -.size (@n) { - // font-size: @n * 1vmin; - // line-height: @n * 1.1vmin; - font-size: @n * 10%; - // line-height: @n * 11%; - line-height: 110%; -} - -.two-part-gradient (@start, @end) { - background: -webkit-linear-gradient(@start, @end); /* For Safari 5.1 to 6.0 */ - background: -o-linear-gradient(@start, @end); /* For Opera 11.1 to 12.0 */ - background: -moz-linear-gradient(@start, @end); /* For Firefox 3.6 to 15 */ - background: linear-gradient(@start, @end); /* Standard syntax */ -} - -.avatar (@width) { - &.avatar { - overflow: hidden; - text-overflow: ellipsis; - font-size: 16px; - display: flex; - align-items: center; - &.clickable { - cursor: pointer; - &:hover { - background-color: rgba(0,0,0,0.3); - } - } - .default, media-tag { - display: inline-flex; - width: @width; - height: @width; - justify-content: center; - align-items: center; - border-radius: 4px; - overflow: hidden; - box-sizing: content-box; - } - .default { - .tools_unselectable(); - background: white; - color: black; - font-size: @width/1.2; - } - .right-col { - order: 10; - flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: flex; - flex-flow: column; - .name { - flex: 1; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .friend { - padding: 0; - } - } - media-tag { - min-height: @width; - min-width: @width; - max-height: @width; - max-width: @width; - img { - min-width: 100%; - min-height: 100%; - max-width: none; - max-height: none; // To override 'media-tag img' in slide.less - } - } - } -} - -.leftsideCategory { - .tools_unselectable(); - padding: 5px 20px; - margin: 15px 0; - cursor: pointer; - height: @toolbar-line-height; - line-height: @toolbar-line-height - 10px; - .fa { - width: 25px; - } - &:hover { - background: rgba(0,0,0,0.05); - } - &.active { - background: white; - } -} - -.fileIcon { - li { - display: inline-block; - margin: 10px 10px; - width: 140px; - height: 140px; - text-align: center; - vertical-align: top; - overflow: hidden; - text-overflow: ellipsis; - padding-top: 5px; - padding-bottom: 5px; - - &:not(.selected):not(.selectedTmp) { - border: 1px solid #CCC; - } - .name { - width: 100%; - height: 48px; - margin: 8px 0; - display: inline-block; - //align-items: center; - //justify-content: center; - overflow: hidden; - //text-overflow: ellipsis; - word-wrap: break-word; - } - .truncated { - display: block; - position: absolute; - bottom: 0px; - left: 0; right: 0; - text-align: center; - } - img.icon { - height: 48px; - max-height: none; - max-width: none; - margin: 8px 0; - } - .fa { - display: block; - margin: auto; - font-size: 48px; - margin: 8px 0; - text-align: center; - &.listonly { - display: none; - } - } - } -} - -.sidebarButton { - button.btn { - background-color: @button-bg; - border-color: darken(@button-bg, 10%); - color: white; - &:hover { - background-color: darken(@button-bg, 10%); - } - &.btn-danger { - background-color: @button-red-bg; - border-color: darken(@button-red-bg, 10%); - color: white; - &:hover { - background-color: darken(@button-red-bg, 10%); - } - } - } -} diff --git a/customize.dist/src/less/sidebar-layout.less b/customize.dist/src/less/sidebar-layout.less deleted file mode 100644 index 47e4e86f9..000000000 --- a/customize.dist/src/less/sidebar-layout.less +++ /dev/null @@ -1,80 +0,0 @@ -@import '/customize/src/less/variables.less'; -@import '/customize/src/less/mixins.less'; -@import (once) "/customize/src/less2/include/colortheme.less"; - -@leftside-bg: @colortheme_sidebar-left-bg; -@leftside-color: @colortheme_sidebar-left-fg; -@rightside-color: @colortheme_sidebar-right-fg; -@description-color: @colortheme_sidebar-description; - -@button-width: 400px; - - -.cp { - input[type="text"] { - padding-left: 10px; - } - #container { - font-size: 16px; - display: flex; - flex: 1; - min-height: 0; - #leftSide { - color: @leftside-color; - width: 250px; - background: @leftside-bg; - display: flex; - flex-flow: column; - .categories { - flex: 1; - .category { - .leftsideCategory(); - } - } - } - #rightSide { - flex: 1; - padding: 5px 20px; - color: @rightside-color; - overflow: auto; - .element { - label:not(.noTitle), .label { - display: block; - font-weight: bold; - margin-bottom: 0; - } - .description { - display: block; - color: @description-color; - margin-bottom: 5px; - } - margin-bottom: 20px; - } - [type="text"], button { - vertical-align: middle; - height: 40px; - box-sizing: border-box; - } - .inputBlock { - display: inline-flex; - width: @button-width; - input { - flex: 1; - border-radius: 0.25em 0 0 0.25em; - border: 1px solid #adadad; - border-right: 0px; - } - button { - border-radius: 0 0.25em 0.25em 0; - //border: 1px solid #adadad; - border-left: 0px; - } - } - &>div { - margin: 10px 0; - } - .sidebarButton; - } - } -} - diff --git a/customize.dist/src/less/toolbar.less b/customize.dist/src/less/toolbar.less deleted file mode 100644 index aadc0b6b0..000000000 --- a/customize.dist/src/less/toolbar.less +++ /dev/null @@ -1,1035 +0,0 @@ -@import "./variables.less"; -@import "./mixins.less"; - -@import (once) "../less2/include/dropdown.less"; -@import (once) "../less2/include/colortheme.less"; -@import (once) "../less2/include/ckeditor-fix.less"; -@import (once) "../less2/include/icon-colors.less"; - -.dropdown_main(); - -.ckeditor_fix(); - -.iconColors_main(); - -.unselectable { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.toolbar-container { - display: flex; -} - -body .userlist-drawer { - font: @main-font-size @colortheme_font; - min-width: 175px; - width: 175px; - display: block; - overflow-y: auto; - overflow-x: hidden; - padding: 10px; - box-sizing: border-box; - .close { - position: absolute; - margin-top: -10px; - margin-left: 149px; - font-size: 15px; - opacity: 0.5; - cursor: pointer; - text-shadow: unset; - &:hover { - opacity: 1; - } - } - h2 { - color: inherit; - text-align: center; - padding: 5px 0px; - margin: 5px 0px; - font: inherit; - font-weight: bold; - white-space: normal; - line-height: auto; - } - text-align:baseline; - .viewer { - font-style: italic; - padding: 5px; - background: rgba(0,0,0,0.1); - margin: 2px 0; - } - - & > p { - font: @main-font-size @colortheme_font; - margin: 0; - padding: 0; - display: block; - } - - .userlist-others { - display: flex; - flex-flow: column; - margin: 10px 0; - margin-bottom: 20px; - &>span { - padding: 5px; - margin: 2px 0; - background: rgba(0,0,0,0.1); - .avatar(30px); - .default, media-tag { - margin-right: 5px; - } - } - } - .friend { - display: inline-block; - width: 20px; - } -} - -body { - .addToolbarColors (@color, @bg-color) { - .userlist-drawer { - background-color: @bgcolor; - color: @color; - h2 { - background-color: darken(@bgcolor, 10%); - color: @color; - } - .friend { - &:hover { - color: darken(@color, 15%); - } - } - } - .cryptpad-toolbar { - background-color: @bgcolor; - color: @color; - .userlist-drawer { - background-color: @bgcolor; - width: 150px; - position: absolute; - left: 0; - top: 96px; - bottom: 0; - .close { - color: @color; - } - } - .cryptpad-spinner, .cryptpad-state { - font-size: @main-font-size; - color: @color; - } - .cryptpad-limit { - text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color; - } - .cryptpad-lag { - .bars { - span { - background: @color; - border: 1px solid darken(@bgcolor, 20%); - } - } - } - .cryptpad-toolbar-leftside, .cryptpad-toolbar-rightside { - background-color: lighten(@bgcolor, 8%); - button:hover, button.active { - background-color: @bgcolor; - } - } - .hoverable:hover { - .editable, .pencilIcon { - cursor: text; - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); - transition: all 0.15s; - color: @color; - } - .editable { - cursor: text; - } - } - .saveIcon { - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); - color: @color; - &:hover { - background: darken(@bgcolor, 5%); - } - } - input { - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); - color: @color; - } - .cp-dropdown-content.cp-dropdown-left a { - color: black; - } - } - } - - &.app-pad { - @bgcolor: @toolbar-pad-bg; - @color: @toolbar-pad-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-code { - @bgcolor: @toolbar-code-bg; - @color: @toolbar-code-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-slide { - @bgcolor: @toolbar-slide-bg; - @color: @toolbar-slide-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-poll { - @bgcolor: @toolbar-poll-bg; - @color: @toolbar-poll-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-whiteboard { - @bgcolor: @toolbar-whiteboard-bg; - @color: @toolbar-whiteboard-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-drive { - @bgcolor: @toolbar-drive-bg; - @color: @toolbar-drive-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-file { - @bgcolor: @toolbar-file-bg; - @color: @toolbar-file-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-contacts { - @bgcolor: @toolbar-friends-bg; - @color: @toolbar-friends-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-settings { - @bgcolor: @toolbar-settings-bg; - @color: @toolbar-settings-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-profile { - @bgcolor: @toolbar-profile-bg; - @color: @toolbar-profile-color; - .addToolbarColors(@color, @bgcolor); - } - &.app-todo { - @bgcolor: @toolbar-todo-bg; - @color: @toolbar-todo-color; - .addToolbarColors(@color, @bgcolor); - } - -} - -body .cryptpad-toolbar { - * { - outline-width: 0; - &:focus { - outline-width: 0; - } - } - - @toolbar-green: #5cb85c; - - box-sizing: border-box; - padding: 0px; - - //background-color: #BBBBFF; - background-color: @toolbar-default-bg; - color: @toolbar-default-color; - - - - .fa { - font: normal normal normal 14px/1 FontAwesome; - font-family: FontAwesome; - } - - .unselectable; - - font: @toolbar-button-font; - width: 100%; - z-index: 10000; // body, .cryptpad-toolbar - - .cp-dropdown-container { - //height: 100%; - //display: inline-block; - button { - height: 100%; - border-radius: 0; - margin: 0; - background: transparent; - } - } - - .separator { - content: ''; - display: inline-block; - background: #888; - margin: 7px 4px; - height: 18px; - width: 1px; - vertical-align: top; - } - .separator:last-child { - display: none; - } - - button { - transition: all 0.15s; - .unselectable(); - &.hidden { - display: none; - } - .drawer { - display: none; - } - // Bootstrap 4 colors (btn-secondary) - border: 1px solid transparent; - color: inherit; - font: @toolbar-button-font; - * { - color: inherit; - font: @toolbar-button-font; - } - } - .cryptpad-toolbar-rightside button, .cryptpad-toolbar-leftside button { - background: transparent; - &:hover { - background-color: rgba(50,50,50,0.3); - } - } - - button.upgrade { - font-size: 14px; - vertical-align: top; - margin-left: 10px; - } - .cryptpad-limit { - box-sizing: border-box; - height: 26px; - width: 26px; - display: inline-block; - padding: 3px; - margin: 0px 3px 0 6px; - vertical-align: middle; - line-height: @toolbar-top-height; - span { - color: red; - cursor: pointer; - margin: auto; - font-size: 20px; - } - } - - .clag () { - background: transparent - } - - .cryptpad-state { - line-height: @toolbar-top-height; - padding: 0 5px; - color: inherit; - &:empty { - display: none; - } - } - .cryptpad-lag { - display: inline-block; - vertical-align: top; - box-sizing: content-box; - text-align: center; - line-height: @toolbar-top-height; - .disconnected { - display: none; - color: inherit; - width: 28px; - margin: 8px; - font-size: 28px; - text-align: center; - vertical-align: middle; - } - .bars { - margin: 8px; - height: 26px; - line-height: 26px; - display: inline-block; - span { - display: inline-block; - width: 6px; - margin: 0; - margin-right: 1px; - background: white; - vertical-align: bottom; - box-sizing: border-box; - border: 1px solid black; - visibility: hidden; - transition: background 1s, border 1s; - &:last-child { - margin-right: 0; - } - &.bar1 { height: 6px; } - &.bar2 { height: 12px; } - &.bar3 { height: 18px; } - &.bar4 { height: 24px; } - } - } - &.dc { - .disconnected { - display: inline; - } - .bars { - display: none - } - } - &.lag0 { - span span { - .clag(); - } - } - &.lag1 { - .bar2, .bar3, .bar4 { .clag(); } - span span { - visibility: visible; - } - } - &.lag2 { - .bar3, .bar4 { .clag(); } - span span { - visibility: visible; - } - } - &.lag3 { - .bar4 { .clag(); } - span span { - visibility: visible; - } - } - &.lag4 { - span span { - visibility: visible; - } - } - } - div { - white-space: normal; - &.cryptpad-back { - padding: 0; - font-weight: bold; - cursor: pointer; - color: #000; - } - } - - button, select, .rightside-element { - height: @toolbar-line-height; - box-sizing: border-box; - padding: 3px 10px; - margin: 0; - - } - - .rightside-button { - float: right; - cursor: pointer; - } - - .leftside-button { - cursor: pointer; - float: left; - } - - .rightside-element { - vertical-align: middle; - white-space: nowrap; - &.float { - float: right; - } - } - - select { - border: 0px; - margin-left: 5px; - margin-right: 5px; - padding-left: 5px; - border: 1px solid #A6A6A6; - border-bottom-color: #979797; - vertical-align: top; - box-sizing: content-box; - option { - height: 24px; - } - } - - .big { - @media screen and (max-width: @media-not-big) { - display: none; - } - @media screen and (min-width: @media-not-small) { - display: inline-block; - } - } - .small { - @media screen and (max-width: @media-not-big) { - display: inline-block; - } - @media screen and (min-width: @media-not-small) { - display: none; - } - } - - .med-big { - @media screen and (max-width: @media-medium-screen) { - display: none; - } - @media screen and (min-width: (@media-medium-screen + 1px)) { - display: inline-block; - } - } - .med-small { - @media screen and (max-width: @media-medium-screen) { - display: inline-block; - } - @media screen and (min-width: (@media-medium-screen + 1px)) { - display: none; - } - } - - .large { - @media screen and (max-width: @media-narrow-screen) { - display: none; - } - @media screen and (min-width: (@media-narrow-screen + 1px)) { - display: inline-block; - } - } - .narrow { - @media screen and (max-width: @media-narrow-screen) { - display: inline-block; - } - @media screen and (min-width: (@media-narrow-screen + 1px)) { - display: none; - } - } - - &.notitle { - .filler { - flex: 1; - } - } - &:not(.notitle) { - .cryptpad-toolbar-top { - @media screen and (max-width: @media-medium-screen) { - flex-wrap: wrap; - height: auto; - .cryptpad-state { - display: none; - } - .filler { - flex: 1; - } - .cryptpad-title { - flex: auto; - width: 100%; - order: 10; - height: @toolbar-line-height; - line-height: initial; - margin: 0; - .hoverable { - width: 100%; - } - .editable { - max-width: ~"calc(100vw - 26px)"; - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - font-size: @main-font-size; - height: @toolbar-line-height; - box-sizing: border-box; - line-height: 20px; - } - .pencilIcon, .saveIcon { - box-sizing: border-box; - height: @toolbar-line-height; - line-height: @main-font-size; - display: inline-block; - - .fa { - font-size: @main-font-size; - } - } - input { - height: @toolbar-line-height; - font-size: @main-font-size; - flex: 1; - max-width: none; - } - } - } - } - } -} - -.app-slide { - @media screen and (max-width: @media-medium-screen) { - .cryptpad-toolbar-leftside { - flex-flow: row wrap; - width: 175px; - height: auto; - .cryptpad-spinner { order: 0; } - } - .cryptpad-toolbar-rightside { - height: 2*@toolbar-line-height; - } - } - @media screen and (max-width: 320px) { - .cryptpad-toolbar-leftside { - flex-flow: row wrap; - width: 175px; - height: auto; - padding-top: @toolbar-line-height; - .cryptpad-spinner { order: 0; } - } - .cryptpad-toolbar-rightside { - height: auto; - } - } -} - -.cryptpad-toolbar-top { - display: flex; - flex-flow: row; - height: @toolbar-top-height; - position: relative; - .filler { - height: 100%; - display: inline-block; - order: 4; - //flex: 1; - } - .cryptpad-title { - flex: 1; - overflow: hidden; - text-overflow: ellipsis; - order: 3; - height: 100%; - display: inline-flex; - align-items: center; - line-height: @toolbar-top-height; - margin: 0 10px; - .title { - font-size: 25px; - vertical-align: middle; - line-height: 48px; //25px; - white-space: nowrap; - } - .pageTitle { - padding: 0 5px; - } - .pencilIcon, .saveIcon { - display: flex; - align-items: center; - font-size: 20px; - vertical-align: middle; - line-height: 20px; - .fa { - font-size: 20px; - } - } - .readOnly { - margin-left: 10px; - font-size: 25px; - font-style: italic; - white-space: nowrap; - } - .hoverable { - display: inline-flex; - overflow: hidden; - } - .pencilIcon { - cursor: pointer; - border: 1px solid transparent; - padding: 5px; - border-collapse: collapse; - span { - cursor: pointer; - } - } - .saveIcon { - cursor: pointer; - padding: 5px; - border-collapse: collapse; - span { - cursor: pointer; - } - } - .editable { - overflow: hidden; - text-overflow: ellipsis; - border: 1px solid transparent; - padding: 5px; - border-collapse: collapse; - } - input { - max-width: ~"calc(100% - 40px)"; - flex: 1; - font-size: 1.5em; - vertical-align: middle; - box-sizing: border-box; - cursor: auto; - width: 300px; - font-size: 20px; - padding: 5px 5px; - height: 40px; - } - } - .cryptpad-link, .cryptpad-new { - font-size: 48px; - line-height: 64px; - width: @toolbar-top-height; - height: @toolbar-top-height; - padding: 0; - box-sizing: border-box; - display: inline-block; - - color: white; - a { - color: white; - } - transition: all 0.15s; - } - .cryptpad-new { - background-color: rgba(0,0,0,0.2); - &:hover { - background-color: rgba(0,0,0,0.3); - } - text-align: center; - font-size: 32px; - margin-left: 10px; - &> button { - display: flex; - align-items: center; - justify-content: center; - width: 64px; - height: 64px !important; // Allows us to have a nice square outline when focused - font-size: 1em; - color: inherit; - height: auto; - padding: 0px; - margin: 0; - &::before { - width: 100%; - text-align: center; - padding-top: 4px; - } - &:hover { - background-color: initial; - border-color: transparent; - } - span { - vertical-align: top; - font-size: 1em; - text-decoration: none; - color: inherit; - } - } - } - .cryptpad-link { - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; - background-color: rgba(0,0,0,0.4); - &:hover { - background-color: rgba(0,0,0,0.5); - } - order: 1; - .fa { - margin: 0; - } - a.cryptpad-logo { - cursor: pointer; - display: inline-flex; - text-decoration: none; - height: auto; - padding: 10px; - - img { - cursor: pointer; - height: 100%; - width: 100%; - } - } - } - .cryptpad-user { - height: 100%; - display: inline-flex; - order: 5; - line-height: @toolbar-top-height; - color: white; - .cryptpad-upgrade { order: 1; } - .cryptpad-new { order: 2; } - .cryptpad-user-dropdown { order: 3; } - .cryptpad-backup { order: 4; } - &> * { - display: inline-block; - height: 100%; - vertical-align: top; - } - .cryptpad-upgrade { - height: @toolbar-line-height; - vertical-align: middle; - cursor: pointer; - } - .cryptpad-user-dropdown { - z-index: 10000; // .cryptpad-user-dropdown - //margin-left: 20px; - height: 64px; - width: 64px; - padding: 0px; - box-sizing: border-box; - text-align: center; - background-color: rgba(0,0,0,0.3); - transition: all 0.15s; - &:hover { - background-color: rgba(0,0,0,0.4); - } - .cp-dropdown-content { - margin: 0; - } - button { - display: flex; - justify-content: center; - align-items: center; - height: 64px; - width: 64px; - padding: 0; - span { - text-align: center; - width: 100%; - cursor: default; - font-size: 32px; - } - &.avatar { - .avatar(48px); - media-tag { - margin: 8px; - } - border: 0; - } - } - } - p.accountData { - &> span { - font-weight: bold; - span { - font-weight: normal; - } - } - } - .cryptpad-backup { - margin: 0; - border-radius: 0; - background: transparent; - &:hover { - background-color: rgba(0,0,0,0.2); - } - } - } -} -.cryptpad-toolbar-leftside { - //height: @toolbar-line-height; - &:empty { - height: 0; - } - float: left; - display: inline-flex; - align-items: center; - //margin-bottom: -1px; - .cryptpad-dropdown-users { - pre { - /* needed for ckeditor */ - white-space: pre; - margin: 5px 0px; - } - } - button { - margin: 0px; - border-radius: 0; - height: 100%; - } - .cp-dropdown-content { - margin-top: -1px; - } - - & > span { - height: @toolbar-line-height; - } - - #userButtons { order: 1; } - .shareButton { order: 2; } - .cryptpad-spinner { order: 3; } - - #userButtons button { - width: 125px; - text-align: center; - } - .shareButton button { - width: 50px; - text-align: center; - } -} -.cryptpad-toolbar-rightside { - min-height: @toolbar-line-height; - overflow: hidden; - &:empty { - min-height: 0; - height: 0; - } - text-align: right; - &> button { - height: 100%; - margin: 0; - border-radius: 0; - padding: 0 10px; - } - .drawer-content:empty ~ .drawer-button { - display: none; - } - .drawer-content { - box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2); - position: absolute; - right:0px; - margin-top: @toolbar-line-height; - min-width: 50px; - background: @dropdown-bg; - display: flex; - flex-flow: column; - z-index:10000; // .drawer-content - color: black; - .fa { - font-size: 17px; - } - &> span { - box-sizing: border-box; - min-width: 150px; - height: @toolbar-line-height; - border-radius: 0; - border: 0; - } - button { - padding: 5px 16px; - text-align: left; - margin: 0; - border-radius: 0; - border: 0; - width: 100%; - line-height: 1em; - .drawer { - margin-left: 10px; - display: inline; - vertical-align: top; - } - &:hover { - background-color: @dropdown-bg-hover !important; - color: @dropdown-color; - } - } - } -} -.cryptpad-toolbar-history { - display: none; - text-align: center; - .next { - display: inline-block; - vertical-align: middle; - margin: 20px; - } - .previous { - display: inline-block; - vertical-align: middle; - margin: 20px; - } - .goto { - display: inline-block; - vertical-align: middle; - text-align: center; - input { width: 75px; } - } - .gotoInput { - vertical-align: middle; - } - button { - color: inherit; - background-color: rgba(0,0,0,0.2); - &:hover { - background-color: rgba(0,0,0,0.4); - } - } - .closeHistory { - background: white; - color: black; - &:hover { - background-color: #e6e6e6; - } - } - .fa-spinner { - font-size: 66px; - } -} -.cke_toolbox .cryptpad-toolbar-history { - input.gotoInput { - padding: 3px 3px; - } -} -.cryptpad-spinner { - line-height: @toolbar-line-height; - padding: 0 20px; - &> span.fa { - height: 20px; - width: 20px; - //margin: 8px; - line-height: 20px; - font-size: 20px; - text-align: center; - } -} -.cryptpad-readonly { - margin-right: 5px; - font-weight: bold; - text-transform: uppercase; -} -.cryptpad-dropdown-share { - a { - .fa { - margin-right: 5px; - } - } -} - -.lag { - height: 15px !important; - width: 15px !important; - border-radius: 50%; - border: 1px solid @cp-outline; -} -.lag-green { - background-color: @cp-green; -} -.lag-red { - background-color: @cp-red; -} -.lag-orange { - background-color: @cp-orange; -} - diff --git a/customize.dist/src/less/topbar.less b/customize.dist/src/less/topbar.less deleted file mode 100644 index 2f7f55edb..000000000 --- a/customize.dist/src/less/topbar.less +++ /dev/null @@ -1,96 +0,0 @@ -@import "./variables.less"; -@import (once) "../less2/include/colortheme.less"; - -#cryptpadTopBar { - background: @topbar-back; - position: relative; - top: 0; - left: 0; - right: 0; - height: @topbar-height; - color: @topbar-color; - font-family: @colortheme_font; - padding: 5px; - box-sizing: border-box; - font-size: 30px; - - border-bottom: 1px solid darken(@topbar-back, 15%); - - &> span { - vertical-align: middle; - display: inline-block; - height: 100%; - } - .cryptpad-logo { - height: 40px; - vertical-align: middle; - } - - .slogan { - font-size: 20px; - color: @topbar-color; - line-height: 40px; - } - - .gotoMain { - color: @topbar-color; - height: 40px; - line-height: 40px; - &:hover { - text-decoration: none; - color: @cp-purple; - } - } - - .right { - float: right; - font-size: 20px; - margin: 0px 10px; - line-height: 40px; - - .buttonSuccess { - // Bootstrap 4 colors - color: #fff; - background: @toolbar-green; - border-color: @toolbar-green; - &:hover { - color: #fff; - background: #449d44; - border: 1px solid #419641; - } - span { - color: #fff; - } - .large { - margin-left: 5px; - } - } - - button { - .cp-dropdown-button-title { - .fa-user { - margin-right: 5px; - } - } - } - &.link a { - font-weight: 500; - font-size: 0.75em; - color: @cp-link; - - &:hover { - color: @cp-link-hover; - text-decoration: underline; - } - &:visited { - color: @cp-link-visited; - } - } - - &.link { - @media screen and (max-width: @media-not-big) { - display: none; - } - } - } -} diff --git a/customize.dist/src/less/variables.less b/customize.dist/src/less/variables.less deleted file mode 100644 index 1d3415d89..000000000 --- a/customize.dist/src/less/variables.less +++ /dev/null @@ -1,118 +0,0 @@ -@import (once) '../less2/include/colortheme.less'; -@import (once) '../less2/include/browser.less'; - -@base: @colortheme_base; -@dark-base: darken(@base, 20%); -@less-dark-base: darken(@base, 10%); -@light-base: @colortheme_light-base; -@less-light-base: lighten(@base, 10%); -@fore: #555; -@old-base: @colortheme_old-base; -@old-fore: @colortheme_old-fore; - -@main-font-size: 16px; - -@cp-green: @colortheme_cp-green; -@cp-accent: lighten(@cp-green, 20%); - -@cp-red: @colortheme_cp-red; -@cp-outline: #444; - -@cp-orange: #FE9A2E; - -@cp-blue: #00CFC1; -@cp-blue: #00ADEE; -@cp-light-blue: #41b7d8; // lighten(@cp-blue, 20%); - -@cp-purple: #558; - -@page-white: #fafafa; - -// links -@cp-link: @cp-light-blue; -@cp-link-visited: @cp-light-blue; -@cp-link-hover: darken(@cp-light-blue, 10%); - - -@slide-default-bg: #000; - -@bg-loading: #222; -@color-loading: @old-fore; - -@media-not-big: @browser_media-not-big; -@media-not-small: @browser_media-not-small; - -@media-short-screen: @browser_media-short-screen; -@media-narrow-screen: @browser_media-narrow-screen; -@media-medium-screen: @browser_media-medium-screen; - - -// Dropdown - -@dropdown-font: @main-font-size @colortheme_font; -@dropdown-bg: #f9f9f9; -@dropdown-color: black; -@dropdown-bg-hover: #f1f1f1; -@dropdown-bg-active: #e8e8e8; - -// Toolbar - -@toolbar-button-font: @dropdown-font; - -@toolbar-pad-bg: @colortheme_pad-bg; -@toolbar-pad-color: @colortheme_pad-color; -@toolbar-slide-bg: @colortheme_slide-bg; -@toolbar-slide-color: @colortheme_slide-color; -@toolbar-code-bg: @colortheme_code-bg; -@toolbar-code-color: @colortheme_code-color; -@toolbar-poll-bg: @colortheme_poll-bg; -@toolbar-poll-color: @colortheme_poll-color; -@toolbar-whiteboard-bg: @colortheme_whiteboard-bg; -@toolbar-whiteboard-color: @colortheme_whiteboard-color; -@toolbar-drive-bg: @colortheme_drive-bg; -@toolbar-drive-color: @colortheme_drive-color; -@toolbar-file-bg: @colortheme_file-bg; -@toolbar-file-color: @colortheme_file-color; -@toolbar-friends-bg: @colortheme_friends-bg; -@toolbar-friends-color: @colortheme_friends-color; -@toolbar-default-bg: @colortheme_default-bg; -@toolbar-default-color: @colortheme_default-color; -@toolbar-settings-bg: @colortheme_settings-bg; -@toolbar-settings-color: @colortheme_settings-color; -@toolbar-profile-bg: @colortheme_profile-bg; -@toolbar-profile-color: @colortheme_profile-color; -@toolbar-todo-bg: @colortheme_todo-bg; -@toolbar-todo-color: @colortheme_todo-color; - -@topbar-back: #fff; -@topbar-color: #000; -@topbar-button-bg: #2E9AFE; -@topbar-button-color: #fff; -@topbar-height: 50px; - -@toolbar-top-height: 64px; - -@main-border-width: 15vw; -@cp-darkblue: #3333ff; -@cp-accent2: darken(@cp-darkblue, 20%); - -@main-block-bg: rgba(200, 200, 200, 0.3); -@main-color: #fff; -@main-bg: url('/customize/bg4.jpg') no-repeat center center; - -@category-bg: #f4f4f4; - -@button-bg: @colortheme_sidebar-button-bg; -@button-alt-bg: @colortheme_sidebar-button-alt-bg; -@button-red-bg: @colortheme_sidebar-button-red-bg; - -.unselectable () { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -@toolbar-line-height: 32px; diff --git a/customize.dist/src/less2/404.less b/customize.dist/src/less2/404.less index ca1c3503e..33a852cd0 100644 --- a/customize.dist/src/less2/404.less +++ b/customize.dist/src/less2/404.less @@ -22,7 +22,7 @@ html.cp-app-print { .app-print_main(); } -body.cp-readonly .cp-hidden-if-readonly { display:none !important; } +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"; } diff --git a/customize.dist/src/less2/include/alertify.less b/customize.dist/src/less2/include/alertify.less index e66f92243..a75a0bb07 100644 --- a/customize.dist/src/less2/include/alertify.less +++ b/customize.dist/src/less2/include/alertify.less @@ -1,6 +1,6 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; @import (once) "./browser.less"; -@import (once) "./modal-theme.less"; +@import (once) "./variables.less"; .alertify_main () { @max-z-index: 2147483647; @@ -21,14 +21,14 @@ @alertify-input-bg: @colortheme_modal-input; @alertify-input-fg: @colortheme_modal-fg; - @alertify_padding-base: @modal_padding; - @alertify_box-shadow: @modal_shadow; + @alertify_padding-base: @variables_padding; + @alertify_box-shadow: @variables_shadow; // Logs to show that something has happened // These show only once .alertify-logs { - z-index:10000; // alertify logs + z-index: 10000; // alertify logs @media print { visibility: hidden; } @@ -152,16 +152,13 @@ input:not(.form-control), textarea { background-color: @alertify-input-bg; - color: @alertify-input-fg; + color: @alertify-input-fg; border: 0px; margin-bottom: 15px; width: 100%; font-size: 100%; padding: @alertify_padding-base; - &:focus { - //outline-offset: -2px; - } } input[type="checkbox"] { @@ -180,7 +177,6 @@ box-sizing: border-box; position: relative; outline: 0; - border: 0; display: inline-block; align-items: center; padding: 0 6px; @@ -226,7 +222,7 @@ border: 1px dotted @alertify-base; } &::-moz-focus-inner { - border:0; + border: 0; } } @@ -244,7 +240,7 @@ &.bottom, &:not(.top) { bottom: 16px; - // Bottom left placement. Default. Use for transitions. + /* // Bottom left placement. Default. Use for transitions. &.left, &:not(.right) { > * { @@ -255,7 +251,7 @@ > * { } - } + }*/ } // All left positions. @@ -293,7 +289,7 @@ &.top { top: 0; - // Top left placement, use for transitions. + /* // Top left placement, use for transitions. &.left, &:not(.right) { > * { @@ -304,7 +300,7 @@ > * { } - } + }*/ } > * { diff --git a/customize.dist/src/less2/include/app-print.less b/customize.dist/src/less2/include/app-print.less index d25110056..957170044 100644 --- a/customize.dist/src/less2/include/app-print.less +++ b/customize.dist/src/less2/include/app-print.less @@ -4,7 +4,7 @@ height: auto; max-height: none; overflow: visible; - display:block; + display: block; @page { margin: 0; size: landscape; diff --git a/customize.dist/src/less2/include/colortheme-all.less b/customize.dist/src/less2/include/colortheme-all.less new file mode 100644 index 000000000..4544da76e --- /dev/null +++ b/customize.dist/src/less2/include/colortheme-all.less @@ -0,0 +1,6 @@ +// Don't override/edit this file directly, you can create +// create a file: customize/src/less2/include/colortheme.less +// override whatever colors you want. When you update, the new colors will be +// added ok because the original file is pulled in first. +@import (once) "/customize.dist/src/less2/include/colortheme.less"; +@import (once) "/customize/src/less2/include/colortheme.less"; diff --git a/customize.dist/src/less2/include/colortheme.less b/customize.dist/src/less2/include/colortheme.less index 4893f5fa2..afa40cfd4 100644 --- a/customize.dist/src/less2/include/colortheme.less +++ b/customize.dist/src/less2/include/colortheme.less @@ -37,47 +37,59 @@ @colortheme_dropdown-bg-hover: #f1f1f1; @colortheme_dropdown-bg-active: #e8e8e8; -// Apps +// Apps, these colors are used for customizing the toolbar for the apps. @colortheme_pad-bg: #1c4fa0; @colortheme_pad-color: #fff; @colortheme_pad-toolbar-bg: #c1e7ff; +@colortheme_pad-warn: #F83A3A; @colortheme_slide-bg: #e57614; @colortheme_slide-color: #fff; +@colortheme_slide-warn: #58D697; @colortheme_code-bg: #ffae00; @colortheme_code-color: #000; +@colortheme_code-warn: #9A37F7; @colortheme_poll-bg: #006304; @colortheme_poll-color: #fff; @colortheme_poll-help-bg: #bbffbb; @colortheme_poll-th-bg: #005bef; @colortheme_poll-th-fg: #fff; +@colortheme_poll-warn: #ffae00; @colortheme_whiteboard-bg: #800080; @colortheme_whiteboard-color: #fff; +@colortheme_whiteboard-warn: #ffae00; @colortheme_drive-bg: #0087ff; @colortheme_drive-color: #fff; +@colortheme_drive-warn: #cd2532; @colortheme_file-bg: #cd2532; @colortheme_file-color: #fff; +@colortheme_file-warn: #ffae00; @colortheme_friends-bg: #607b8d; @colortheme_friends-color: #fff; +@colortheme_friends-warn: #cd2532; @colortheme_default-bg: #ddd; @colortheme_default-color: #000; +@colortheme_default-warn: #cd2532; @colortheme_settings-bg: #0087ff; @colortheme_settings-color: #fff; +@colortheme_settings-warn: #cd2532; @colortheme_profile-bg: #0087ff; @colortheme_profile-color: #fff; +@colortheme_profile-warn: #cd2532; @colortheme_todo-bg: #7bccd1; @colortheme_todo-color: #000; +@colortheme_todo-warn: #cd2532; // Sidebar layout (profile / settings) @colortheme_sidebar-active: #fff; @@ -91,7 +103,7 @@ @colortheme_sidebar-button-red-bg: #e54e4e; @colortheme_sidebar-button-alt-bg: #fff; -@cryptpad_color_blue: #4591C4; +@cryptpad_color_blue: #4591C4; @cryptpad_color_grey: #999999; @cryptpad_header_col: #1E1F1F; @cryptpad_text_col: #3F4141; diff --git a/customize.dist/src/less2/include/creation.less b/customize.dist/src/less2/include/creation.less new file mode 100644 index 000000000..c7b795e4f --- /dev/null +++ b/customize.dist/src/less2/include/creation.less @@ -0,0 +1,143 @@ +@import (once) "./colortheme-all.less"; +@import (once) "./tools.less"; + +.creation_main() { + .tippy-popper { + z-index: 100000001 !important; + } + #cp-creation-container { + position: absolute; + z-index: 100000000; // #loading * 10 + top: 0px; + background: @colortheme_loading-bg; + color: @colortheme_loading-color; + display: flex; + align-items: center; + width: 100%; + height: 100%; + overflow: auto; + @media screen and (max-height: 600px), screen and (max-width: 500px) { + align-items: baseline; + } + } + #cp-creation { + text-align: center; + font: @colortheme_app-font; + width: 100%; + & > div { + width: 60vw; + max-width: 100%; + margin: 40px auto; + text-align: left; + display: flex; + flex-wrap: wrap; + justify-content: center; + align-items: center; + h2, p { + width: 100%; + } + h2 { + display: flex; + justify-content: space-between; + .cp-creation-help { + display: none; + } + } + @media screen and (max-width: 500px) { + width: ~"calc(100% - 30px)"; + } + @media screen and (max-height: 600px), screen and (max-width: 500px) { + h2 .cp-creation-help { + display: inline; + } + p { + display: none; + } + } + @media screen and (min-height: 601px) { + @media screen and (min-width: 501px) { + p { + display: block !important; + } + } + } + } + + .cp-creation-create { + button { + .tools_unselectable(); + padding: 15px; + background: darken(@colortheme_loading-bg, 10%); + color: @colortheme_loading-color; + margin: 3px 10px; + border: none; + cursor: pointer; + &:hover { + background: darken(@colortheme_loading-bg, 5%); + } + } + } + + input[type="radio"] { + display: none; + &:checked { + & + label { + font-weight: bold; + background-color: lighten(@colortheme_loading-bg, 20%); + cursor: default; + border: 1px solid #c1158e; + &:hover { + background-color: lighten(@colortheme_loading-bg, 20%); + } + } + } + } + input[type="radio"] + label { + .tools_unselectable(); + display: inline-flex; + align-items: center; + justify-content: center; + width: 200px; + height: 50px; + padding: 5px; + margin: 0 20px; + border: 1px solid @colortheme_loading-color; + cursor: pointer; + &:hover { + background-color: lighten(@colortheme_loading-bg, 10%); + } + } + .cp-creation-expire { + #cp-creation-expire-true { + display: none; + &:checked { + & + label { + height: 100px; + .cp-creation-expire-picker { + display: inline; + } + } + } + } + label[for="cp-creation-expire-true"] { + flex-wrap: wrap; + .cp-creation-expire-picker { + display: none; + } + input { + width: 70px; + } + select { + width: 100px; + } + input, select { + border: none; + height: 30px; + background: @colortheme_loading-bg; + color: @colortheme_loading-color; + border-radius: 3px; + } + } + } + } +} diff --git a/customize.dist/src/less2/include/dropdown.less b/customize.dist/src/less2/include/dropdown.less index 1aea222bd..3cf32537e 100644 --- a/customize.dist/src/less2/include/dropdown.less +++ b/customize.dist/src/less2/include/dropdown.less @@ -1,4 +1,4 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; @import (once) "./tools.less"; /* The container
- needed to position the dropdown content */ @@ -13,7 +13,7 @@ } button { - .fa-caret-down{ + .fa-caret-down { margin-right: 0px; margin-left: 5px; } diff --git a/customize.dist/src/less2/include/fileupload.less b/customize.dist/src/less2/include/fileupload.less index a07d365bd..3ed3e793e 100644 --- a/customize.dist/src/less2/include/fileupload.less +++ b/customize.dist/src/less2/include/fileupload.less @@ -1,4 +1,4 @@ -@import (once) './colortheme.less'; +@import (once) './colortheme-all.less'; @import (once) './modal.less'; .fileupload_main () { diff --git a/customize.dist/src/less2/include/font.less b/customize.dist/src/less2/include/font.less index 33eb3dd3d..ec8e77f0f 100644 --- a/customize.dist/src/less2/include/font.less +++ b/customize.dist/src/less2/include/font.less @@ -1,7 +1,7 @@ .font_neuropolitical () { @font-face { font-family: Neuropolitical; - src: url(/customize/fonts/neuropolitical.ttf) + src: url("/customize/fonts/neuropolitical.ttf"); } } .font_open-sans () { diff --git a/customize.dist/src/less2/include/framework.less b/customize.dist/src/less2/include/framework.less new file mode 100644 index 000000000..4bdb2b0b8 --- /dev/null +++ b/customize.dist/src/less2/include/framework.less @@ -0,0 +1,18 @@ +@import (once) "./toolbar.less"; +@import (once) './fileupload.less'; +@import (once) './alertify.less'; +@import (once) './tokenfield.less'; +@import (once) './creation.less'; + +.framework_main(@bg-color, @warn-color, @color) { + .toolbar_main( + @bg-color: @bg-color, + @warn-color: @warn-color, + @color: @color + ); + .fileupload_main(); + .alertify_main(); + .tokenfield_main(); + .creation_main(); +} + diff --git a/customize.dist/src/less2/include/icon-colors.less b/customize.dist/src/less2/include/icon-colors.less index db9de2a14..b787fee1c 100644 --- a/customize.dist/src/less2/include/icon-colors.less +++ b/customize.dist/src/less2/include/icon-colors.less @@ -1,4 +1,4 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; .iconColors_main () { // Classes used in common-interface.js .cp-icon-color-pad { color: @colortheme_pad-bg; } @@ -12,7 +12,7 @@ .cp-icon-color-settings { color: @colortheme_settings-bg; } .cp-icon-color-profile { color: @colortheme_settings-bg; } .cp-icon-color-default { color: @colortheme_default-bg; } - .cp-icon-color-todo { color:@colortheme_todo-bg; } + .cp-icon-color-todo { color: @colortheme_todo-bg; } .cp-border-color-pad { border-color: @colortheme_pad-bg !important; } .cp-border-color-code { border-color: @colortheme_code-bg !important; } @@ -25,6 +25,6 @@ .cp-border-color-settings { border-color: @colortheme_settings-bg !important; } .cp-border-color-profile { border-color: @colortheme_settings-bg !important; } .cp-border-color-default { border-color: @colortheme_default-bg !important; } - .cp-border-color-todo { border-color:@colortheme_todo-bg !important; } + .cp-border-color-todo { border-color: @colortheme_todo-bg !important; } } diff --git a/customize.dist/src/less2/include/infopages.less b/customize.dist/src/less2/include/infopages.less index 41bafa6f0..3c3bdef5e 100644 --- a/customize.dist/src/less2/include/infopages.less +++ b/customize.dist/src/less2/include/infopages.less @@ -1,4 +1,4 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; @infopages_infobar-height: 64px; @infopages_padding: 32px; @@ -89,7 +89,6 @@ color: #fff; padding-top: 30%; margin-bottom: 0; - } } @@ -152,8 +151,8 @@ } } -// navigation top bar -.navbar { +// navigation top bar +.navbar { background: #fff; .navbar-brand { display: block; diff --git a/customize.dist/src/less2/include/leftside-menu.less b/customize.dist/src/less2/include/leftside-menu.less index 3211fb3a9..28ae57af4 100644 --- a/customize.dist/src/less2/include/leftside-menu.less +++ b/customize.dist/src/less2/include/leftside-menu.less @@ -1,6 +1,6 @@ @import (once) "./unselectable.less"; @import (once) "./variables.less"; -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; .leftside-menu_main() { } diff --git a/customize.dist/src/less2/include/limit-bar.less b/customize.dist/src/less2/include/limit-bar.less index efca7811d..7faf2d916 100644 --- a/customize.dist/src/less2/include/limit-bar.less +++ b/customize.dist/src/less2/include/limit-bar.less @@ -1,4 +1,4 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; .limit-bar_main () { .cp-limit-container { @@ -27,7 +27,7 @@ background: blue; position: absolute; left: 0; - z-index:1; // .usage + z-index: 1; // .usage &.cp-limit-usage-normal { background: @colortheme_green; } diff --git a/customize.dist/src/less2/include/modal-theme.less b/customize.dist/src/less2/include/modal-theme.less deleted file mode 100644 index 1ed183d2d..000000000 --- a/customize.dist/src/less2/include/modal-theme.less +++ /dev/null @@ -1,4 +0,0 @@ -// Used in modal.less and alertify.less -@modal_padding: 12px; -@modal_shadow: 0 8px 32px 0 rgba(0,0,0,.4); - diff --git a/customize.dist/src/less2/include/modal.less b/customize.dist/src/less2/include/modal.less index 865abff73..3bd674527 100644 --- a/customize.dist/src/less2/include/modal.less +++ b/customize.dist/src/less2/include/modal.less @@ -1,12 +1,12 @@ -@import (once) "./colortheme.less"; -@import (once) "./modal-theme.less"; +@import (once) "./colortheme-all.less"; +@import (once) "./variables.less"; .modal_base() { font-family: @colortheme_font; background-color: @colortheme_modal-bg; color: @colortheme_modal-fg; - box-shadow: @modal_shadow; + box-shadow: @variables_shadow; a { color: @colortheme_modal-link; @@ -31,9 +31,9 @@ .cp-modal { background-color: @colortheme_modal-bg; color: @colortheme_modal-fg; - box-shadow: @modal_shadow; + box-shadow: @variables_shadow; - padding: @modal_padding; + padding: @variables_padding; position: absolute; top: 15vh; bottom: 15vh; @@ -71,7 +71,7 @@ position: absolute; top: 0; right: 0; - margin: @modal_padding; + margin: @variables_padding; cursor: pointer; } } diff --git a/customize.dist/src/less2/include/sidebar-layout.less b/customize.dist/src/less2/include/sidebar-layout.less index 2d667cee5..89d23d946 100644 --- a/customize.dist/src/less2/include/sidebar-layout.less +++ b/customize.dist/src/less2/include/sidebar-layout.less @@ -1,4 +1,4 @@ -@import (once) "/customize/src/less2/include/colortheme.less"; +@import (once) "/customize/src/less2/include/colortheme-all.less"; @import (once) "/customize/src/less2/include/leftside-menu.less"; @leftside-bg: @colortheme_sidebar-left-bg; diff --git a/customize.dist/src/less2/include/tokenfield.less b/customize.dist/src/less2/include/tokenfield.less index 5dcea83ec..6604b4481 100644 --- a/customize.dist/src/less2/include/tokenfield.less +++ b/customize.dist/src/less2/include/tokenfield.less @@ -59,7 +59,6 @@ padding-right: 4px; } &.active { - border-color: #52a8ec; border-color: rgba(82, 168, 236, 0.8); } &.duplicate { diff --git a/customize.dist/src/less2/include/toolbar-history.less b/customize.dist/src/less2/include/toolbar-history.less index d553caa3f..abf14f3ac 100644 --- a/customize.dist/src/less2/include/toolbar-history.less +++ b/customize.dist/src/less2/include/toolbar-history.less @@ -1,4 +1,4 @@ -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; .history_main () { .cp-toolbar-history { diff --git a/customize.dist/src/less2/include/toolbar.less b/customize.dist/src/less2/include/toolbar.less index 5143e4872..9335058b5 100644 --- a/customize.dist/src/less2/include/toolbar.less +++ b/customize.dist/src/less2/include/toolbar.less @@ -1,5 +1,5 @@ @import (once) "./dropdown.less"; -@import (once) "./colortheme.less"; +@import (once) "./colortheme-all.less"; @import (once) "./browser.less"; @import (once) "./ckeditor-fix.less"; @import (once) "./avatar.less"; @@ -7,8 +7,12 @@ @import (once) "./icon-colors.less"; @import (once) "./tools.less"; - -.toolbar_main () { +.toolbar_main ( + @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 + @barWidth: 600px // width of the toolbar +) { @toolbar_line-height: 32px; @toolbar_top-height: 64px; @@ -51,7 +55,7 @@ } .cp-toolbar-userlist-drawer { - background-color: @colortheme_default-bg; + background-color: @bg-color; font: @colortheme_app-font-size @colortheme_font; min-width: 175px; width: 175px; @@ -82,7 +86,7 @@ white-space: normal; line-height: auto; } - text-align:baseline; + text-align: baseline; .cp-toolbar-userlist-viewer { font-style: italic; padding: 5px; @@ -169,162 +173,53 @@ } } - .addToolbarColors (@color, @bg-color, @barWidth: 600px) { - .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(@bgcolor, 8%); - } - &.cp-markdown-help { float: right; } + // TODO(cjd) This ought to be in a less file for markdown-based editors + .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; } } - .cp-toolbar-userlist-drawer { - background-color: @bgcolor; + } + .cp-toolbar-userlist-drawer { + background-color: @bg-color; + color: @color; + .cp-toolbar-userlist-drawer-close { color: @color; - .cp-toolbar-userlist-drawer-close { - color: @color; - } - h2 { - background-color: darken(@bgcolor, 10%); - color: @color; - } - .cp-toolbar-userlist-name-input { - background-color: darken(@bg-color, 10%); - color: @color; - } - .cp-toolbar-userlist-name-edit { - color: contrast(@color, - lighten(@color, 20%), - darken(@color, 20%)); - background: transparent; - &:hover { - color: @color; - } - } - .cp-toolbar-userlist-friend { - &:hover { - color: darken(@color, 15%); - } - } } - .cp-toolbar { - background-color: @bgcolor; + h2 { + background-color: darken(@bg-color, 10%); color: @color; - .cp-toolbar-spinner { - font-size: @colortheme_app-font-size; - color: @color; - } - .cp-toolbar-limit { - text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color; - } - .cp-toolbar-leftside, .cp-toolbar-rightside { - background-color: lighten(@bgcolor, 8%); - button:hover, button.cp-toolbar-button-active { - background-color: @bgcolor; - } - } - .cp-toolbar-rightside { - @media screen and (max-width: @barWidth) { // 450px - flex-wrap: wrap; - height: auto; - width: 100%; - } - } - .cp-toolbar-title-hoverable:hover { - .cp-toolbar-title-editable, .cp-toolbar-title-edit { - cursor: text; - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); - transition: all 0.15s; - color: @color; - } - .cp-toolbar-title-editable { - cursor: text; - } - } - .cp-toolbar-title-save { - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); - color: @color; - &:hover { - background: darken(@bgcolor, 5%); - } - } - input { - border: 1px solid darken(@bgcolor, 15%); - background: darken(@bgcolor, 10%); + } + .cp-toolbar-userlist-name-input { + background-color: darken(@bg-color, 10%); + color: @color; + } + .cp-toolbar-userlist-name-edit { + color: contrast(@color, + lighten(@color, 20%), + darken(@color, 20%)); + background: transparent; + &:hover { color: @color; } - .cp-dropdown-content.cp-dropdown-left a { - color: black; + } + .cp-toolbar-userlist-friend { + &:hover { + color: darken(@color, 15%); } } } - &.cp-app-pad { - @bgcolor: @colortheme_pad-bg; - @color: @colortheme_pad-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-code { - @bgcolor: @colortheme_code-bg; - @color: @colortheme_code-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-slide { - @bgcolor: @colortheme_slide-bg; - @color: @colortheme_slide-color; - .addToolbarColors(@color, @bgcolor, 700px); - } - &.cp-app-poll { - @bgcolor: @colortheme_poll-bg; - @color: @colortheme_poll-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-whiteboard { - @bgcolor: @colortheme_whiteboard-bg; - @color: @colortheme_whiteboard-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-drive { - @bgcolor: @colortheme_drive-bg; - @color: @colortheme_drive-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-file { - @bgcolor: @colortheme_file-bg; - @color: @colortheme_file-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-contacts { - @bgcolor: @colortheme_friends-bg; - @color: @colortheme_friends-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-settings { - @bgcolor: @colortheme_settings-bg; - @color: @colortheme_settings-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-profile { - @bgcolor: @colortheme_profile-bg; - @color: @colortheme_profile-color; - .addToolbarColors(@color, @bgcolor); - } - &.cp-app-todo { - @bgcolor: @colortheme_todo-bg; - @color: @colortheme_todo-color; - .addToolbarColors(@color, @bgcolor); - } - .cp-toolbar { * { outline-width: 0; @@ -340,12 +235,8 @@ display: flex; flex-wrap: wrap; justify-content: space-between; - - //background-color: #BBBBFF; - background-color: @colortheme_default-bg; - color: @colortheme_default-color; - - + background-color: @bg-color; + color: @color; .fa { font: normal normal normal 14px/1 FontAwesome; @@ -383,7 +274,6 @@ vertical-align: middle; line-height: @toolbar_top-height; span { - color: red; cursor: pointer; margin: auto; font-size: 20px; @@ -407,7 +297,6 @@ } select { - border: 0px; margin-left: 5px; margin-right: 5px; padding-left: 5px; @@ -421,7 +310,7 @@ } &.cp-toolbar-notitle { - .cp-toolbar-top-filler { + .cp-toolbar-top-filler { flex: 1; } } @@ -430,7 +319,7 @@ @media screen and (max-width: @browser_media-medium-screen) { flex-wrap: wrap; height: auto; - .cp-toolbar-top-filler { + .cp-toolbar-top-filler { flex: 1; } .cp-toolbar-title { @@ -473,6 +362,56 @@ } } } + + .cp-toolbar-spinner { + font-size: @colortheme_app-font-size; + color: @color; + } + .cp-toolbar-limit { + text-shadow: -1px 0 @color, 0 1px @color, 1px 0 @color, 0 -1px @color; + color: @warn-color; + } + .cp-toolbar-leftside, .cp-toolbar-rightside { + background-color: lighten(@bg-color, 8%); + button:hover, button.cp-toolbar-button-active { + background-color: @bg-color; + } + } + .cp-toolbar-rightside { + @media screen and (max-width: @barWidth) { // 450px + flex-wrap: wrap; + height: auto; + width: 100%; + } + } + .cp-toolbar-title-hoverable:hover { + .cp-toolbar-title-editable, .cp-toolbar-title-edit { + cursor: text; + border: 1px solid darken(@bg-color, 15%); + background: darken(@bg-color, 10%); + transition: all 0.15s; + color: @color; + } + .cp-toolbar-title-editable { + cursor: text; + } + } + .cp-toolbar-title-save { + border: 1px solid darken(@bg-color, 15%); + background: darken(@bg-color, 10%); + color: @color; + &:hover { + background: darken(@bg-color, 5%); + } + } + input { + border: 1px solid darken(@bg-color, 15%); + background: darken(@bg-color, 10%); + color: @color; + } + .cp-dropdown-content.cp-dropdown-left a { + color: black; + } } .cp-toolbar-top { @@ -481,10 +420,45 @@ height: @toolbar_top-height; position: relative; width: 100%; + + .cp-pad-not-pinned { + order: 4; + flex: 1; + + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + + align-self: center; + padding-left: 20px; + padding-right: 5px; + font-size: @colortheme_app-font-size; + color: @warn-color; + .cp-pnp-msg { + padding-left: 5px; + font-family: @colortheme_font; + font-size: @colortheme_app-font-size; + a { + font-size: @colortheme_app-font-size; + font-weight: bold; + color: @warn-color; + &:hover { + text-decoration: underline; + } + } + @media screen and (max-width: (@browser_media-not-big)) { + display: none; + } + } + @media screen and (max-width: (@browser_media-not-big)) { + overflow: visible; + max-width: 20px; + } + } .cp-toolbar-top-filler { height: @toolbar_top-height; display: inline-block; - order: 4; + order: 5; //flex: 1; } .cp-toolbar-title { @@ -555,7 +529,6 @@ input { max-width: ~"calc(100% - 40px)"; flex: 1; - font-size: 1.5em; vertical-align: middle; box-sizing: border-box; cursor: auto; @@ -593,10 +566,9 @@ align-items: center; justify-content: center; width: 64px; - height: 64px !important; // Allows us to have a nice square outline when focused font-size: 1em; color: inherit; - height: auto; + height: 64px; padding: 0px; margin: 0; &::before { @@ -646,7 +618,7 @@ .cp-toolbar-user { height: @toolbar_top-height; display: inline-flex; - order: 5; + order: 6; line-height: @toolbar_top-height; color: white; .cp-toolbar-new { order: 2; } @@ -772,13 +744,13 @@ .cp-toolbar-drawer-content { box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2); position: absolute; - right:0px; + right: 0px; margin-top: @toolbar_line-height; min-width: 50px; background: @colortheme_dropdown-bg; display: flex; flex-flow: column; - z-index:10000; //Z cp-toolbar-drawer-content + z-index: 10000; //Z cp-toolbar-drawer-content color: black; .fa { font-size: 17px; diff --git a/customize.dist/src/less2/include/variables.less b/customize.dist/src/less2/include/variables.less index 3aee02492..ba6c642e2 100644 --- a/customize.dist/src/less2/include/variables.less +++ b/customize.dist/src/less2/include/variables.less @@ -1,3 +1,9 @@ +// This is a file for generic constants which we didn't want to hardcode everywhere. +// However, unlike colortheme, customizing these variables will cause breakage. + // Elements size @variables_bar-height: 32px; +// Used in modal.less and alertify.less +@variables_padding: 12px; +@variables_shadow: 0 8px 32px 0 rgba(0,0,0,.4); diff --git a/customize.dist/src/less2/loading.less b/customize.dist/src/less2/loading.less index 504e1e393..e13a56de6 100644 --- a/customize.dist/src/less2/loading.less +++ b/customize.dist/src/less2/loading.less @@ -3,7 +3,7 @@ WARNING: THIS FILE DOES NOTHING It exists only as a proposal of what CSS you should use in loading.js The CSS inside of loading.js is precompiled in order to save 200ish milliseconds to the loading screen. */ -@import (once) "./include/colortheme.less"; +@import (once) "./include/colortheme-all.less"; @import (once) "./include/browser.less"; #cp-loading { diff --git a/customize.dist/src/less2/main.less b/customize.dist/src/less2/main.less index ca1c3503e..a2e0e89bd 100644 --- a/customize.dist/src/less2/main.less +++ b/customize.dist/src/less2/main.less @@ -22,7 +22,7 @@ html.cp-app-print { .app-print_main(); } -body.cp-readonly .cp-hidden-if-readonly { display:none !important; } +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"; } @@ -37,4 +37,5 @@ 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"; } diff --git a/customize.dist/src/less2/pages/page-404.less b/customize.dist/src/less2/pages/page-404.less index 6c67732fd..c6afae5b0 100644 --- a/customize.dist/src/less2/pages/page-404.less +++ b/customize.dist/src/less2/pages/page-404.less @@ -1,4 +1,4 @@ -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; @import (once) "../include/font.less"; .font_neuropolitical(); .font_open-sans(); diff --git a/customize.dist/src/less2/pages/page-about.less b/customize.dist/src/less2/pages/page-about.less index d356fecd0..83354abd7 100644 --- a/customize.dist/src/less2/pages/page-about.less +++ b/customize.dist/src/less2/pages/page-about.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); @@ -44,7 +44,7 @@ } } } - .cp-bio-avatar-right { + .cp-bio-avatar-right { padding-right: 15px; padding-left: 0; @media (max-width: 991px) { @@ -112,4 +112,4 @@ } .cp-margin-bot { margin-bottom: 1.5em; -} +} diff --git a/customize.dist/src/less2/pages/page-contact.less b/customize.dist/src/less2/pages/page-contact.less index a8ce6fa04..4d2f9ad0e 100644 --- a/customize.dist/src/less2/pages/page-contact.less +++ b/customize.dist/src/less2/pages/page-contact.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); @@ -12,7 +12,7 @@ } .cp-container { background: #fff; - .cp-iconCont{ + .cp-iconCont { h4 { margin-top: 1.5em; margin-bottom: 1.5em; @@ -31,7 +31,7 @@ @media (max-width: 1200px) and (min-width: 769px) { min-height: 139px; } - @media (max-width: 768px) and (min-width: 576px){ + @media (max-width: 768px) and (min-width: 576px) { min-height: 164px; } @media (max-width: 496px) { diff --git a/customize.dist/src/less2/pages/page-index.less b/customize.dist/src/less2/pages/page-index.less index 90a765a4a..55671f913 100644 --- a/customize.dist/src/less2/pages/page-index.less +++ b/customize.dist/src/less2/pages/page-index.less @@ -1,8 +1,5 @@ -//@import (once) "./variables.less"; - @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; - +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); @@ -96,13 +93,13 @@ body { } @callout-padding: 15px; a:hover { - text-decoration: none + text-decoration: none; } .bs-callout { display: flex; align-items: stretch; margin: 25px 0; - background:rgba(255,255,255,0.6); + background: rgba(255,255,255,0.6); color: black; transition: all .1s ease-in-out; box-sizing: border-box; @@ -139,10 +136,7 @@ h4 { .bs-callout:hover { //color: white; transform: scale(1.05); - cursor: pointer; -} -.bs-callout:hover .fa { - //width: 100%; + cursor: pointer; } .bs-callout:hover.cp-callout-more { transform: none !important; @@ -164,7 +158,6 @@ h4 { .cp-callout-recent .fa { background-color: @colortheme_drive-bg; } .cp-hidden { display: none !important; } .cp-callout-more { - width: auto; display: inline-block; align-content: center; height: 2em; diff --git a/customize.dist/src/less2/pages/page-login.less b/customize.dist/src/less2/pages/page-login.less index 2b8064486..77dead84c 100644 --- a/customize.dist/src/less2/pages/page-login.less +++ b/customize.dist/src/less2/pages/page-login.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; @import (once) "../include/alertify.less"; @import (once) "../loading.less"; @@ -12,15 +12,12 @@ display: flex; align-items: center; justify-content: space-between; - width: 100%; - .login { - } } } .cp-container { #data { - background: #4591C4; + background: #4591C4; padding-top: 3em; padding-bottom: 7em; padding-left: 30px; @@ -61,7 +58,7 @@ border-radius: 0; &:hover { transform: scale(1.05); - } + } } } } diff --git a/customize.dist/src/less2/pages/page-privacy.less b/customize.dist/src/less2/pages/page-privacy.less index 59fa4b1fd..a1f8b2955 100644 --- a/customize.dist/src/less2/pages/page-privacy.less +++ b/customize.dist/src/less2/pages/page-privacy.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); diff --git a/customize.dist/src/less2/pages/page-register.less b/customize.dist/src/less2/pages/page-register.less index af2e06d51..6336c6aa3 100644 --- a/customize.dist/src/less2/pages/page-register.less +++ b/customize.dist/src/less2/pages/page-register.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; @import (once) "../include/alertify.less"; @import (once) "../loading.less"; @@ -52,14 +52,22 @@ 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 { - background: #4591C4; /* fallback for old browsers */ - background: -webkit-linear-gradient(to right, #FF7C4F, #4592C4); /* Chrome 10-25, Safari 5.1-6 */ - background: linear-gradient(to right, #FF7C4F, #4592C4); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */ + // 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; diff --git a/customize.dist/src/less2/pages/page-terms.less b/customize.dist/src/less2/pages/page-terms.less index 59fa4b1fd..a1f8b2955 100644 --- a/customize.dist/src/less2/pages/page-terms.less +++ b/customize.dist/src/less2/pages/page-terms.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); diff --git a/customize.dist/src/less2/pages/page-what-is-cryptpad.less b/customize.dist/src/less2/pages/page-what-is-cryptpad.less index cf127e1ec..0e02ce41a 100644 --- a/customize.dist/src/less2/pages/page-what-is-cryptpad.less +++ b/customize.dist/src/less2/pages/page-what-is-cryptpad.less @@ -1,5 +1,5 @@ @import (once) "../include/infopages.less"; -@import (once) "../include/colortheme.less"; +@import (once) "../include/colortheme-all.less"; .infopages_main(); .infopages_topbar(); @@ -28,7 +28,7 @@ color: @cryptpad_header_col; } p { - color: @cryptpad_text_col + color: @cryptpad_text_col; } #zeroknowledge { width: 65%; @@ -40,4 +40,4 @@ display: block; margin: 0 auto; } -} \ No newline at end of file +} diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 0ba3413a3..e490cd040 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -156,7 +156,7 @@ define(function () { out.filePickerButton = "Intégrer un fichier stocké dans CryptDrive"; out.filePicker_close = "Fermer"; - out.filePicker_description = "Choisissez un fichier de votre CryptDrive pour l'intégrer ou uploadez-en un nouveau"; + out.filePicker_description = "Choisissez un fichier de votre CryptDrive pour l'intégrer ou importez-en un nouveau"; out.filePicker_filter = "Filtrez les fichiers par leur nom"; out.or = 'ou'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index b83b54930..cd1e88511 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -31,6 +31,7 @@ define(function () { out.typeError = "This pad is not compatible with the selected application"; out.onLogout = 'You are logged out, click here to log in
or press Escape to access your pad in read-only mode.'; out.wrongApp = "Unable to display the content of that realtime session in your browser. Please try to reload that page."; + out.padNotPinned = 'This pad will expire in 3 months, {0}login{1} or {2}register{3} to preserve it.'; out.loading = "Loading..."; out.error = "Error"; @@ -786,5 +787,24 @@ define(function () { out.feedback_privacy = "We care about your privacy, and at the same time we want CryptPad to be very easy to use. We use this file to figure out which UI features matter to our users, by requesting it along with a parameter specifying which action was taken."; out.feedback_optout = "If you would like to opt out, visit your user settings page, where you'll find a checkbox to enable or disable user feedback"; + // Creation page + out.creation_404 = "This pad not longer exists. Use the following form to create a new pad"; + out.creation_ownedTitle = "Type of pad"; + out.creation_ownedTrue = "Owned pad"; + out.creation_ownedFalse = "Open pad"; + out.creation_owned1 = "An owned pad is a pad that you can delete from the server whenever you want. Once it is deleted, no one else can access it, even if it is stored in their CryptDrive."; + out.creation_owned2 = "An open pad doesn't have any owner and thus, it can't be deleted from the server unless it has reached its expiration time."; + out.creation_expireTitle = "Life time"; + out.creation_expireTrue = "Add a life time"; + out.creation_expireFalse = "Unlimited"; + out.creation_expireHours = "Hours"; + out.creation_expireDays = "Days"; + out.creation_expireMonths = "Months"; + out.creation_expire1 = "By default, a pad stored by a registered users will never be removed from the server, unless it is requested by its owner."; + out.creation_expire2 = "If you prefer, you can set a life time to make sure the pad will be permanently deleted from the server and unavailable after the specified date."; + out.creation_createTitle = "Create a pad"; + out.creation_createFromTemplate = "From template"; + out.creation_createFromScratch = "From scratch"; + return out; }); diff --git a/package.json b/package.json index c87e16e26..72e7bf4e7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cryptpad", "description": "realtime collaborative visual editor with zero knowlege server", - "version": "1.21.0", + "version": "1.22.0", "dependencies": { "chainpad-server": "^1.0.1", "express": "~4.10.1", @@ -11,15 +11,19 @@ "ws": "^1.0.1" }, "devDependencies": { + "flow-bin": "^0.59.0", "jshint": "~2.9.1", - "selenium-webdriver": "^2.53.1", "less": "2.7.1", - "flow-bin": "^0.59.0" + "lesshint": "^4.5.0", + "selenium-webdriver": "^2.53.1" }, "scripts": { "start": "node server.js", "dev": "DEV=1 node server.js", - "lint": "jshint --config .jshintrc --exclude-path .jshintignore .", + "fresh": "FRESH=1 node server.js", + "lint": "jshint --config .jshintrc --exclude-path .jshintignore . && ./node_modules/lesshint/bin/lesshint -c ./.lesshintrc ./customize.dist/src/less2/", + "lint:js": "jshint --config .jshintrc --exclude-path .jshintignore .", + "lint:less": "./node_modules/lesshint/bin/lesshint -c ./.lesshintrc ./customize.dist/src/less2/", "flow": "./node_modules/.bin/flow", "test": "node TestSelenium.js", "template": "cd customize.dist/src && for page in ../index.html ../privacy.html ../terms.html ../about.html ../contact.html ../what-is-cryptpad.html ../../www/login/index.html ../../www/register/index.html ../../www/settings/index.html ../../www/user/index.html;do echo $page; cp template.html $page; done;" diff --git a/pinned.js b/pinned.js new file mode 100644 index 000000000..372ed2d10 --- /dev/null +++ b/pinned.js @@ -0,0 +1,74 @@ +/* jshint esversion: 6, node: true */ +const Fs = require('fs'); +const Semaphore = require('saferphore'); +const nThen = require('nthen'); + +const sema = Semaphore.create(20); + +let dirList; +const fileList = []; +const pinned = {}; + +const hashesFromPinFile = (pinFile, fileName) => { + var pins = {}; + pinFile.split('\n').filter((x)=>(x)).map((l) => JSON.parse(l)).forEach((l) => { + switch (l[0]) { + case 'RESET': { + pins = {}; + //jshint -W086 + // fallthrough + } + case 'PIN': { + l[1].forEach((x) => { pins[x] = 1; }); + break; + } + case 'UNPIN': { + l[1].forEach((x) => { delete pins[x]; }); + break; + } + default: throw new Error(JSON.stringify(l) + ' ' + fileName); + } + }); + return Object.keys(pins); +}; + +module.exports.load = function (cb) { + nThen((waitFor) => { + Fs.readdir('./pins', waitFor((err, list) => { + if (err) { throw err; } + dirList = list; + })); + }).nThen((waitFor) => { + fileList.splice(0, fileList.length); + dirList.forEach((f) => { + sema.take((returnAfter) => { + Fs.readdir('./pins/' + f, waitFor(returnAfter((err, list2) => { + if (err) { throw err; } + list2.forEach((ff) => { fileList.push('./pins/' + f + '/' + ff); }); + }))); + }); + }); + }).nThen((waitFor) => { + fileList.forEach((f) => { + sema.take((returnAfter) => { + Fs.readFile(f, waitFor(returnAfter((err, content) => { + if (err) { throw err; } + const hashes = hashesFromPinFile(content.toString('utf8'), f); + hashes.forEach((x) => { + (pinned[x] = pinned[x] || {})[f.replace(/.*\/([^/]*).ndjson$/, (x, y)=>y)] = 1; + }); + }))); + }); + }); + }).nThen(() => { + cb(pinned); + }); +}; + +if (!module.parent) { + module.exports.load(function (data) { + Object.keys(data).forEach(function (x) { + console.log(x + ' ' + JSON.stringify(data[x])); + }); + }); +} \ No newline at end of file diff --git a/rpc.js b/rpc.js index dc5c539e3..410e5f22b 100644 --- a/rpc.js +++ b/rpc.js @@ -10,6 +10,7 @@ var Fs = require("fs"); var Path = require("path"); var Https = require("https"); const Package = require('./package.json'); +const Pinned = require('./pinned'); var RPC = module.exports; @@ -212,7 +213,6 @@ var checkSignature = function (signedMsg, signature, publicKey) { }; var loadUserPins = function (Env, publicKey, cb) { - var pinStore = Env.pinStore; var session = beginSession(Env.Sessions, publicKey); if (session.channels) { @@ -230,7 +230,7 @@ var loadUserPins = function (Env, publicKey, cb) { pins[channel] = false; }; - pinStore.getMessages(publicKey, function (msg) { + Env.pinStore.getMessages(publicKey, function (msg) { // handle messages... var parsed; try { @@ -325,9 +325,8 @@ var getFileSize = function (Env, channel, cb) { }; var getMultipleFileSize = function (Env, channels, cb) { - var msgStore = Env.msgStore; if (!Array.isArray(channels)) { return cb('INVALID_PIN_LIST'); } - if (typeof(msgStore.getChannelSize) !== 'function') { + if (typeof(Env.msgStore.getChannelSize) !== 'function') { return cb('GET_CHANNEL_SIZE_UNSUPPORTED'); } @@ -526,6 +525,53 @@ var sumChannelSizes = function (sizes) { .reduce(function (a, b) { return a + b; }, 0); }; +// inform that the +var loadChannelPins = function (Env) { + Pinned.load(function (data) { + Env.pinnedPads = data; + Env.evPinnedPadsReady.fire(); + }); +}; +var addPinned = function ( + Env, + publicKey /*:string*/, + channelList /*Array*/, + cb /*:()=>void*/) +{ + Env.evPinnedPadsReady.reg(() => { + channelList.forEach((c) => { + const x = Env.pinnedPads[c] = Env.pinnedPads[c] || {}; + x[publicKey] = 1; + }); + cb(); + }); +}; +var removePinned = function ( + Env, + publicKey /*:string*/, + channelList /*Array*/, + cb /*:()=>void*/) +{ + Env.evPinnedPadsReady.reg(() => { + channelList.forEach((c) => { + const x = Env.pinnedPads[c]; + if (!x) { return; } + delete x[publicKey]; + }); + cb(); + }); +}; +var isChannelPinned = function (Env, channel, cb) { + Env.evPinnedPadsReady.reg(() => { + if (Env.pinnedPads[channel] && Object.keys(Env.pinnedPads[channel]).length) { + cb(true); + } else { + delete Env.pinnedPads[channel]; + cb(false); + } + }); +}; + var pinChannel = function (Env, publicKey, channels, cb) { if (!channels && channels.filter) { return void cb('INVALID_PIN_LIST'); @@ -561,6 +607,7 @@ var pinChannel = function (Env, publicKey, channels, cb) { toStore.forEach(function (channel) { session.channels[channel] = true; }); + addPinned(Env, publicKey, toStore, () => {}); getHash(Env, publicKey, cb); }); }); @@ -569,7 +616,6 @@ var pinChannel = function (Env, publicKey, channels, cb) { }; var unpinChannel = function (Env, publicKey, channels, cb) { - var pinStore = Env.pinStore; if (!channels && channels.filter) { // expected array return void cb('INVALID_PIN_LIST'); @@ -587,13 +633,13 @@ var unpinChannel = function (Env, publicKey, channels, cb) { return void getHash(Env, publicKey, cb); } - pinStore.message(publicKey, JSON.stringify(['UNPIN', toStore]), + Env.pinStore.message(publicKey, JSON.stringify(['UNPIN', toStore]), function (e) { if (e) { return void cb(e); } toStore.forEach(function (channel) { delete session.channels[channel]; }); - + removePinned(Env, publicKey, toStore, () => {}); getHash(Env, publicKey, cb); }); }); @@ -601,7 +647,6 @@ var unpinChannel = function (Env, publicKey, channels, cb) { var resetUserPins = function (Env, publicKey, channelList, cb) { if (!Array.isArray(channelList)) { return void cb('INVALID_PIN_LIST'); } - var pinStore = Env.pinStore; var session = beginSession(Env.Sessions, publicKey); if (!channelList.length) { @@ -632,13 +677,18 @@ var resetUserPins = function (Env, publicKey, channelList, cb) { They will not be able to pin additional pads until they upgrade or delete enough files to go back under their limit. */ if (pinSize > limit[0] && session.hasPinned) { return void(cb('E_OVER_LIMIT')); } - pinStore.message(publicKey, JSON.stringify(['RESET', channelList]), + Env.pinStore.message(publicKey, JSON.stringify(['RESET', channelList]), function (e) { if (e) { return void cb(e); } channelList.forEach(function (channel) { pins[channel] = true; }); + var oldChannels = Object.keys(session.channels); + removePinned(Env, publicKey, oldChannels, () => { + addPinned(Env, publicKey, channelList, ()=>{}); + }); + // update in-memory cache IFF the reset was allowed. session.channels = pins; getHash(Env, publicKey, function (e, hash) { @@ -906,6 +956,7 @@ var isUnauthenticatedCall = function (call) { return [ 'GET_FILE_SIZE', 'GET_MULTIPLE_FILE_SIZE', + 'IS_CHANNEL_PINNED', ].indexOf(call) !== -1; }; @@ -921,10 +972,31 @@ var isAuthenticatedCall = function (call) { 'GET_LIMIT', 'UPLOAD_COMPLETE', 'UPLOAD_CANCEL', - 'EXPIRE_SESSION', + 'EXPIRE_SESSION' ].indexOf(call) !== -1; }; +const mkEvent = function (once) { + var handlers = []; + var fired = false; + return { + reg: function (cb) { + if (once && fired) { return void setTimeout(cb); } + handlers.push(cb); + }, + unreg: function (cb) { + if (handlers.indexOf(cb) === -1) { throw new Error("Not registered"); } + handlers.splice(handlers.indexOf(cb), 1); + }, + fire: function () { + if (once && fired) { return; } + fired = true; + var args = Array.prototype.slice.call(arguments); + handlers.forEach(function (h) { h.apply(null, args); }); + } + }; +}; + /*::const ConfigType = require('./config.example.js');*/ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function)=>void*/) { // load pin-store... @@ -936,14 +1008,19 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) return typeof(config[key]) === 'string'? config[key]: def; }; - var Env = {}; - Env.defaultStorageLimit = config.defaultStorageLimit; - - Env.maxUploadSize = config.maxUploadSize || (20 * 1024 * 1024); - - var Sessions = Env.Sessions = {}; + var Env = { + defaultStorageLimit: config.defaultStorageLimit, + maxUploadSize: config.maxUploadSize || (20 * 1024 * 1024), + Sessions: {}, + paths: {}, + msgStore: (undefined /*:any*/), + pinStore: (undefined /*:any*/), + pinnedPads: {}, + evPinnedPadsReady: mkEvent(true) + }; - var paths = Env.paths = {}; + var Sessions = Env.Sessions; + var paths = Env.paths; var pinPath = paths.pin = keyOrDefaultString('pinPath', './pins'); var blobPath = paths.blob = keyOrDefaultString('blobPath', './blob'); var blobStagingPath = paths.staging = keyOrDefaultString('blobStagingPath', './blobstage'); @@ -970,17 +1047,19 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) } respond(e, [null, dict, null]); }); + case 'IS_CHANNEL_PINNED': + return void isChannelPinned(Env, msg[1], function (isPinned) { + respond(null, [null, isPinned, null]); + }); default: console.error("unsupported!"); return respond('UNSUPPORTED_RPC_CALL', msg); } }; - var rpc = function ( - ctx /*:{ store: Object }*/, - data /*:Array>*/, - respond /*:(?string, ?Array)=>void*/) - { + var rpc0 = function (ctx, data, respond) { + if (!Env.msgStore) { Env.msgStore = ctx.store; } + if (!Array.isArray(data)) { return void respond('INVALID_ARG_FORMAT'); } @@ -1059,8 +1138,6 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) Respond('E_ACCESS_DENIED'); }; - if (!Env.msgStore) { Env.msgStore = ctx.store; } - var handleMessage = function (privileged) { if (config.logRPC) { console.log(msg[0]); } switch (msg[0]) { @@ -1191,6 +1268,19 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) handleMessage(session.privilege); }; + var rpc = function ( + ctx /*:{ store: Object }*/, + data /*:Array>*/, + respond /*:(?string, ?Array)=>void*/) + { + try { + return rpc0(ctx, data, respond); + } catch (e) { + console.log("Error from RPC with data " + JSON.stringify(data)); + console.log(e.stack); + } + }; + var updateLimitDaily = function () { updateLimits(config, undefined, function (e) { if (e) { @@ -1201,6 +1291,8 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) updateLimitDaily(); setInterval(updateLimitDaily, 24*3600*1000); + loadChannelPins(Env); + Store.create({ filePath: pinPath, }, function (s) { diff --git a/server.js b/server.js index 53e7bb9ad..771d055af 100644 --- a/server.js +++ b/server.js @@ -32,6 +32,13 @@ if (DEV_MODE) { console.log("DEV MODE ENABLED"); } +var FRESH_MODE = !!process.env.FRESH; +var FRESH_KEY = ''; +if (FRESH_MODE) { + console.log("FRESH MODE ENABLED"); + FRESH_KEY = +new Date(); +} + const clone = (x) => (JSON.parse(JSON.stringify(x))); var setHeaders = (function () { @@ -102,6 +109,7 @@ app.use("/blob", Express.static(Path.join(__dirname, (config.blobPath || './blob app.use("/customize", Express.static(__dirname + '/customize')); app.use("/customize", Express.static(__dirname + '/customize.dist')); +app.use("/customize.dist", Express.static(__dirname + '/customize.dist')); app.use(/^\/[^\/]*$/, Express.static('customize')); app.use(/^\/[^\/]*$/, Express.static('customize.dist')); @@ -135,7 +143,7 @@ app.get('/api/config', function(req, res){ 'var obj = ' + JSON.stringify({ requireConf: { waitSeconds: 60, - urlArgs: 'ver=' + Package.version + (DEV_MODE? '-' + (+new Date()): ''), + urlArgs: 'ver=' + Package.version + (FRESH_KEY? '-' + FRESH_KEY: '') + (DEV_MODE? '-' + (+new Date()): ''), }, removeDonateButton: (config.removeDonateButton === true), allowSubscriptions: (config.allowSubscriptions === true), diff --git a/www/assert/frame/frame.html b/www/assert/frame/frame.html new file mode 100644 index 000000000..8d2d63c0d --- /dev/null +++ b/www/assert/frame/frame.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/www/assert/frame/frame.js b/www/assert/frame/frame.js new file mode 100644 index 000000000..42808f6f9 --- /dev/null +++ b/www/assert/frame/frame.js @@ -0,0 +1,147 @@ +(function () { + + var Frame = {}; + + var uid = function () { + return Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)) + .toString(32).replace(/\./g, ''); + }; + + // create an invisible iframe with a given source + // append it to a parent element + // execute a callback when it has loaded + Frame.create = function (parent, src, onload, timeout) { + var iframe = document.createElement('iframe'); + + timeout = timeout || 10000; + var to = window.setTimeout(function () { + onload('[timeoutError] could not load iframe at ' + src); + }, timeout); + + iframe.setAttribute('id', 'cors-store'); + + iframe.onload = function (e) { + onload(void 0, iframe, e); + window.clearTimeout(to); + }; + // We must pass a unique parameter here to avoid cache problems in Firefox with + // the NoScript plugin: if the iframe's content is taken from the cache, the JS + // is not executed with NoScript.... + iframe.setAttribute('src', src + '?t=' + new Date().getTime()); + + iframe.style.display = 'none'; + parent.appendChild(iframe); + }; + + /* given an iframe with an rpc script loaded, create a frame object + with an asynchronous 'send' method */ + Frame.open = function (e, A, timeout) { + var win = e.contentWindow; + + var frame = {}; + frame.id = uid(); + + var listeners = {}; + var timeouts = {}; + + timeout = timeout || 5000; + + frame.accepts = function (o) { + return A.some(function (e) { + switch (typeof(e)) { + case 'string': return e === o; + case 'object': return e.test(o); + } + }); + }; + + var changeHandlers = frame.changeHandlers = []; + + frame.change = function (f) { + if (typeof(f) !== 'function') { + throw new Error('[Frame.change] expected callback'); + } + changeHandlers.push(f); + }; + + var _listener = function (e) { + if (!frame.accepts(e.origin)) { + console.log("message from %s rejected!", e.origin); + return; + } + var message = JSON.parse(e.data); + var uid = message._uid; + var error = message.error; + var data = message.data; + + if (!uid) { + console.log("No uid!"); + return; + } + + if (uid === 'change' && changeHandlers.length) { + changeHandlers.forEach(function (f) { + f(data); + }); + return; + } + + if (timeouts[uid]) { + window.clearTimeout(timeouts[uid]); + } + if (listeners[uid]) { + listeners[uid](error, data, e); + delete listeners[uid]; + } + }; + window.addEventListener('message', _listener); + + frame.close = function () { + window.removeEventListener('message', _listener); + }; + + /* method (string): (set|get|remove) + key (string) + data (string) + cb (function) */ + frame.send = function (method, content, cb) { + var req = { + method: method, + //key: key, + data: content, //data, + }; + + var id = req._uid = uid(); + // uid must not equal 'change' + while(id === 'change') { + id = req._uid = uid(); + } + + if (typeof(cb) === 'function') { + //console.log("setting callback!"); + listeners[id] = cb; + //console.log("setting timeout of %sms", timeout); + timeouts[id] = window.setTimeout(function () { + // when the callback is executed it will clear this timeout + cb('[TimeoutError] request timed out after ' + timeout + 'ms'); + }, timeout); + } else { + console.log(typeof(cb)); + } + + win.postMessage(JSON.stringify(req), '*'); + }; + + return frame; + }; + + if (typeof(module) !== 'undefined' && module.exports) { + module.exports = Frame; + } else if (typeof(define) === 'function' && define.amd) { + define(['jquery'], function () { + return Frame; + }); + } else { + window.Frame = Frame; + } +}()); diff --git a/www/assert/frame/respond.js b/www/assert/frame/respond.js new file mode 100644 index 000000000..07f8e2994 --- /dev/null +++ b/www/assert/frame/respond.js @@ -0,0 +1,32 @@ +var validDomains = [ /.*/i, ]; +var isValidDomain = function (o) { + return validDomains.some(function (e) { + switch (typeof(e)) { + case 'string': return e === o; + case 'object': return e.test(o); + } + }); +}; + +window.addEventListener('message', function(e) { + if (!isValidDomain(e.origin)) { return; } + var payload = JSON.parse(e.data); + var parent = window.parent; + var respond = function (error, data) { + var res = { + _uid: payload._uid, + error: error, + data: data, + }; + parent.postMessage(JSON.stringify(res), '*'); + }; + + //console.error(payload); + switch(payload.method) { + case undefined: + return respond('No method supplied'); + default: + return respond(void 0, "EHLO"); + } +}); + diff --git a/www/assert/main.js b/www/assert/main.js index e88e13fd1..2dd3fef5a 100644 --- a/www/assert/main.js +++ b/www/assert/main.js @@ -137,7 +137,8 @@ define([ var secret = Hash.parsePadUrl('/pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy'); return cb(secret.hashData.channel === "67b8385b07352be53e40746d2be6ccd7" && secret.hashData.key === "XAYSuJYYqa9NfmInyHci7LNy" && - secret.hashData.version === 0); + secret.hashData.version === 0 && + typeof(secret.hashData.getURL) === 'function'); }, "Old hash failed to parse"); // make sure version 1 hashes parse correctly @@ -249,7 +250,6 @@ define([ } }; - var evt = Util.mkEvent(); var respond = function (e, out) { evt.fire(e, out); @@ -259,9 +259,8 @@ define([ try { var parsed = JSON.parse(raw); var txid = parsed.txid; - var message = parsed.message; setTimeout(function () { - service(message.command, message.content, function (e, result) { + service(parsed.q, parsed.content, function (e, result) { respond(JSON.stringify({ txid: txid, error: e, @@ -285,33 +284,56 @@ define([ }); }, "Test rpc factory"); -/* assert(function (cb) { - var getBlob = function (url, cb) { - var xhr = new XMLHttpRequest(); - xhr.open("GET", url, true); - xhr.responseType = "blob"; - xhr.onload = function () { - cb(void 0, this.response); - }; - xhr.send(); - }; - - var $img = $('img#thumb-orig'); - getBlob($img.attr('src'), function (e, blob) { - console.log(e, blob); - Thumb.fromImageBlob(blob, function (e, thumb) { - console.log(thumb); - var th = new Image(); - th.src = URL.createObjectURL(thumb); - th.onload = function () { - $(document.body).append($(th).addClass('thumb')); - cb(th.width === Thumb.dimension && th.height === Thumb.dimension); - }; + require([ + '/assert/frame/frame.js', + ], function (Frame) { + Frame.create(document.body, '/assert/frame/frame.html', function (e, frame) { + if (e) { return cb(false); } + + var channel = Frame.open(frame, [ + /.*/i, + ], 5000); + + channel.send('HELO', null, function (e, res) { + if (res === 'EHLO') { return cb(true); } + cb(false); + }); }); }); - }); -*/ + }, "PEWPEW"); + + (function () { + var guid = Wire.uid(); + + var t = Wire.tracker({ + timeout: 1000, + hook: function (txid, q, content) { + console.info(JSON.stringify({ + guid: guid, + txid: txid, + q: q, + content: content, + })); + }, + }); + + assert(function (cb) { + t.call('SHOULD_TIMEOUT', null, function (e) { + if (e === 'TIMEOUT') { return cb(true); } + cb(false); + }); + }, 'tracker should timeout'); + + assert(function (cb) { + var id = t.call('SHOULD_NOT_TIMEOUT', null, function (e, out) { + if (e) { return cb(false); } + if (out === 'YES') { return cb(true); } + cb(false); + }); + t.respond(id, void 0, 'YES'); + }, "tracker should not timeout"); + }()); Drive.test(assert); diff --git a/www/bounce/main.js b/www/bounce/main.js index 74a0d0154..5b122f074 100644 --- a/www/bounce/main.js +++ b/www/bounce/main.js @@ -1,5 +1,5 @@ -define([], function () { - if (window.localStorage && window.localStorage.FS_hash) { +define(['/api/config'], function (ApiConfig) { + if (ApiConfig.httpSafeOrigin !== window.location.origin) { window.alert('The bounce application must only be used from the sandbox domain, ' + 'please report this issue on https://github.com/xwiki-labs/cryptpad'); return; diff --git a/www/code/app-code.less b/www/code/app-code.less index 2541431ea..463bb07a3 100644 --- a/www/code/app-code.less +++ b/www/code/app-code.less @@ -1,14 +1,13 @@ @import (once) "../../customize/src/less2/include/browser.less"; -@import (once) "../../customize/src/less2/include/toolbar.less"; @import (once) "../../customize/src/less2/include/markdown.less"; -@import (once) '../../customize/src/less2/include/fileupload.less'; -@import (once) '../../customize/src/less2/include/alertify.less'; -@import (once) '../../customize/src/less2/include/tokenfield.less'; +@import (once) "../../customize/src/less2/include/framework.less"; -.toolbar_main(); -.fileupload_main(); -.alertify_main(); -.tokenfield_main(); + +.framework_main( + @bg-color: @colortheme_code-bg, + @warn-color: @colortheme_code-warn, + @color: @colortheme_code-color +); // body &.cp-app-code { @@ -51,7 +50,7 @@ height: 100%; overflow: hidden; &.cp-app-code-present { - .CodeMirror { display: none; } + #cp-app-code-container { display: none; } #cp-app-code-preview { border: 0; } } } @@ -96,7 +95,7 @@ } @media (max-width: @browser_media-medium-screen) { - .CodeMirror { + #cp-app-code-container { flex: 1; max-width: 100%; resize: none; @@ -104,6 +103,6 @@ #cp-app-code-preview { display: none !important; } -} + } } diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 2bbf2c7e2..d7d95e78a 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -125,7 +125,7 @@ Version 1 url += ret.type + '/'; if (!ret.hashData) { return url; } if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; } - if (ret.hashData.version !== 1) { throw new Error("Only v1 hashes are managed here."); } + if (ret.hashData.version !== 1) { return url + '#' + ret.hash; } url += '#/' + ret.hashData.version + '/' + ret.hashData.mode + '/' + ret.hashData.channel.replace(/\//g, '-') + diff --git a/www/common/common-interface.js b/www/common/common-interface.js index cb3e5b16a..9323c0bc1 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -55,6 +55,7 @@ define([ }; var stopListening = UI.stopListening = function (handler) { + if (!handler) { return; } // we don't want to stop all the 'keyup' listeners $(window).off('keyup', handler); }; @@ -130,10 +131,19 @@ define([ element: target || h('input'), }; var $t = t.tokenfield = $(t.element).tokenfield(); - t.getTokens = function () { - return $t.tokenfield('getTokens').map(function (token) { + + t.getTokens = function (ignorePending) { + var tokens = $t.tokenfield('getTokens').map(function (token) { return token.value.toLowerCase(); }); + if (ignorePending) { return tokens; } + + var $pendingEl = $($t.parent().find('.token-input')[0]); + var val = ($pendingEl.val() || "").trim(); + if (val && tokens.indexOf(val) === -1) { + return tokens.concat(val); + } + return tokens; }; var $root = $t.parent(); @@ -145,7 +155,7 @@ define([ $t.on('tokenfield:createtoken', function (ev) { var val; ev.attrs.value = ev.attrs.value.toLowerCase(); - if (t.getTokens().some(function (t) { + if (t.getTokens(true).some(function (t) { if (t === ev.attrs.value) { return ((val = t)); } })) { ev.preventDefault(); @@ -210,7 +220,7 @@ define([ var $cancel = findCancelButton(tagger).click(function (e) { close(null, e); }); - listenForKeys(function () { + listener = listenForKeys(function () { $ok.click(); }, function () { $cancel.click(); diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index c22cd28a4..c8bb6f1c7 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -6,11 +6,12 @@ define([ '/common/common-language.js', '/common/common-interface.js', '/common/common-feedback.js', + '/common/hyperscript.js', '/common/media-tag.js', '/customize/messages.js', 'css!/common/tippy.css', -], function ($, Config, Util, Hash, Language, UI, Feedback, MediaTag, Messages) { +], function ($, Config, Util, Hash, Language, UI, Feedback, h, MediaTag, Messages) { var UIElements = {}; // Configure MediaTags to use our local viewer @@ -387,7 +388,6 @@ define([ common.getAttribute(['general', 'markdown-help'], function (e, data) { if (e) { return void console.error(e); } if (data === true && $toolbarButton.length && tbState) { - console.log($toolbar.is(':visible')); $toolbarButton.click(); } }); @@ -1120,5 +1120,169 @@ define([ }); }; + UIElements.getPadCreationScreen = function (common, cb) { + if (!common.isLoggedIn()) { return void cb(); } + var sframeChan = common.getSframeChannel(); + var metadataMgr = common.getMetadataMgr(); + var type = metadataMgr.getMetadataLazy().type; + + var $body = $('body'); + var $creationContainer = $('
', { id: 'cp-creation-container' }).appendTo($body); + var $creation = $('
', { id: 'cp-creation' }).appendTo($creationContainer); + + var setHTML = function (e, html) { + e.innerHTML = html; + return e; + }; + + // Title + $creation.append(h('h1.cp-creation-title', Messages['button_new'+type])); + + // Deleted pad warning + if (metadataMgr.getPrivateData().isDeleted) { + $creation.append(h('div.cp-creation-deleted', Messages.creation_404)); + } + + var createHelper = function (text) { + var q = h('span.cp-creation-help.fa.fa-question', { + title: text + }); + return q; + }; + + // Owned pads + var owned = h('div.cp-creation-owned', [ + h('h2', [ + Messages.creation_ownedTitle, + createHelper(Messages.creation_owned1 + '\n' + Messages.creation_owned2) + ]), + setHTML(h('p'), Messages.creation_owned1 + '
' + Messages.creation_owned2), + h('input#cp-creation-owned-true.cp-creation-owned-value', { + type: 'radio', + name: 'cp-creation-owned', + value: 1, + checked: 'checked' + }), + h('label', { 'for': 'cp-creation-owned-true' }, Messages.creation_ownedTrue), + h('input#cp-creation-owned-false.cp-creation-owned-value', { + type: 'radio', + name: 'cp-creation-owned', + value: 0 + }), + h('label', { 'for': 'cp-creation-owned-false' }, Messages.creation_ownedFalse) + ]); + $creation.append(owned); + + // Life time + var expire = h('div.cp-creation-expire', [ + h('h2', [ + Messages.creation_expireTitle, + createHelper(Messages.creation_expire1, Messages.creation_expire2) + ]), + setHTML(h('p'), Messages.creation_expire1 + '
' + Messages.creation_expire2), + h('input#cp-creation-expire-false.cp-creation-expire-value', { + type: 'radio', + name: 'cp-creation-expire', + value: 0, + checked: 'checked' + }), + h('label', { 'for': 'cp-creation-expire-false' }, Messages.creation_expireFalse), + h('input#cp-creation-expire-true.cp-creation-expire-value', { + type: 'radio', + name: 'cp-creation-expire', + value: 1 + }), + h('label', { 'for': 'cp-creation-expire-true' }, [ + Messages.creation_expireTrue, + h('span.cp-creation-expire-picker', [ + h('input#cp-creation-expire-val', { + type: "number", + min: 1, + max: 100, + value: 3 + }), + h('select#cp-creation-expire-unit', [ + h('option', { value: 'hour' }, Messages.creation_expireHours), + h('option', { value: 'day' }, Messages.creation_expireDays), + h('option', { + value: 'month', + selected: 'selected' + }, Messages.creation_expireMonths) + ]) + ]) + ]) + ]); + $creation.append(expire); + + // Create the pad + var create = function (template) { + // Type of pad + var ownedVal = parseInt($('input[name="cp-creation-owned"]:checked').val()); + // Life time + var expireVal = 0; + if(parseInt($('input[name="cp-creation-expire"]:checked').val())) { + var unit = 0; + switch ($('#cp-creation-expire-unit').val()) { + case "hour" : unit = 3600; break; + case "day" : unit = 3600 * 24; break; + case "month": unit = 3600 * 24 * 30; break; + default: unit = 0; + } + expireVal = ($('#cp-creation-expire-val').val() || 0) * unit; + } + + // XXX TODO remove these lines + ownedVal = undefined; + expire = undefined; + + sframeChan.query("Q_CREATE_PAD", { + owned: ownedVal, + expire: expireVal, + template: template + }, function () { + $creationContainer.remove(); + cb(); + }); + }; + + var $create = $(h('div.cp-creation-create', [ + h('h2', Messages.creation_createTitle) + ])).appendTo($creation); + // Pick a template? + sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) { + if (!data) { return; } + var $templateButton = $('