Merge branch 'soon'
commit
4cf3e0edf8
@ -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 }
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
@import (once) "../less2/include/dropdown.less";
|
|
||||||
|
|
||||||
.dropdown_main();
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
@ -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";
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -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);
|
|
||||||
|
|
@ -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
|
// Elements size
|
||||||
@variables_bar-height: 32px;
|
@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);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (once) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme.less";
|
@import (once) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
.infopages_main();
|
||||||
.infopages_topbar();
|
.infopages_topbar();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
@import (once) "../include/infopages.less";
|
@import (once) "../include/infopages.less";
|
||||||
@import (once) "../include/colortheme.less";
|
@import (once) "../include/colortheme-all.less";
|
||||||
|
|
||||||
.infopages_main();
|
.infopages_main();
|
||||||
.infopages_topbar();
|
.infopages_topbar();
|
||||||
|
@ -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]));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="respond.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}());
|
@ -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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 XWiki SAS
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
define([], function () {
|
||||||
|
var USE_HISTORY = true;
|
||||||
|
|
||||||
|
var verbose = function (x) { console.log(x); };
|
||||||
|
verbose = function () {}; // comment out to enable verbose logging
|
||||||
|
|
||||||
|
var unBencode = function (str) { return str.replace(/^\d+:/, ''); };
|
||||||
|
|
||||||
|
var start = function (conf) {
|
||||||
|
var channel = conf.channel;
|
||||||
|
var validateKey = conf.validateKey;
|
||||||
|
var readOnly = conf.readOnly || false;
|
||||||
|
var network = conf.network;
|
||||||
|
var onConnect = conf.onConnect || function () { };
|
||||||
|
var onMessage = conf.onMessage;
|
||||||
|
var onJoin = conf.onJoin;
|
||||||
|
var onLeave = conf.onLeave;
|
||||||
|
var onReady = conf.onReady;
|
||||||
|
var onDisconnect = conf.onDisconnect;
|
||||||
|
var owners = conf.owners;
|
||||||
|
var password = conf.password;
|
||||||
|
var expire = conf.expire;
|
||||||
|
conf = undefined;
|
||||||
|
|
||||||
|
var initializing = true;
|
||||||
|
var lastKnownHash;
|
||||||
|
|
||||||
|
var messageFromOuter = function () {};
|
||||||
|
|
||||||
|
var onRdy = function () {
|
||||||
|
// Trigger onReady only if not ready yet. This is important because the history keeper sends a direct
|
||||||
|
// message through "network" when it is synced, and it triggers onReady for each channel joined.
|
||||||
|
if (!initializing) { return; }
|
||||||
|
onReady();
|
||||||
|
//sframeChan.event('EV_RT_READY', null);
|
||||||
|
// we're fully synced
|
||||||
|
initializing = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// shim between chainpad and netflux
|
||||||
|
var msgIn = function (peerId, msg) {
|
||||||
|
return msg.replace(/^cp\|/, '');
|
||||||
|
|
||||||
|
/*try {
|
||||||
|
var decryptedMsg = Crypto.decrypt(msg, validateKey);
|
||||||
|
return decryptedMsg;
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return msg;
|
||||||
|
}*/
|
||||||
|
};
|
||||||
|
|
||||||
|
var msgOut = function (msg) {
|
||||||
|
if (readOnly) { return; }
|
||||||
|
return msg;
|
||||||
|
/*try {
|
||||||
|
var cmsg = Crypto.encrypt(msg);
|
||||||
|
if (msg.indexOf('[4') === 0) { cmsg = 'cp|' + cmsg; }
|
||||||
|
return cmsg;
|
||||||
|
} catch (err) {
|
||||||
|
console.log(msg);
|
||||||
|
throw err;
|
||||||
|
}*/
|
||||||
|
};
|
||||||
|
|
||||||
|
var onMsg = function(peer, msg, wc, network, direct) {
|
||||||
|
// unpack the history keeper from the webchannel
|
||||||
|
var hk = network.historyKeeper;
|
||||||
|
|
||||||
|
if (direct && peer !== hk) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (direct) {
|
||||||
|
var parsed = JSON.parse(msg);
|
||||||
|
if (parsed.validateKey && parsed.channel) {
|
||||||
|
if (parsed.channel === wc.id && !validateKey) {
|
||||||
|
validateKey = parsed.validateKey;
|
||||||
|
}
|
||||||
|
// We have to return even if it is not the current channel:
|
||||||
|
// we don't want to continue with other channels messages here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parsed.state && parsed.state === 1 && parsed.channel) {
|
||||||
|
if (parsed.channel === wc.id) {
|
||||||
|
onRdy();
|
||||||
|
}
|
||||||
|
// We have to return even if it is not the current channel:
|
||||||
|
// we don't want to continue with other channels messages here
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (peer === hk) {
|
||||||
|
// if the peer is the 'history keeper', extract their message
|
||||||
|
var parsed1 = JSON.parse(msg);
|
||||||
|
msg = parsed1[4];
|
||||||
|
// Check that this is a message for our channel
|
||||||
|
if (parsed1[3] !== wc.id) { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
lastKnownHash = msg.slice(0,64);
|
||||||
|
var message = msgIn(peer, msg);
|
||||||
|
|
||||||
|
verbose(message);
|
||||||
|
|
||||||
|
// slice off the bencoded header
|
||||||
|
// Why are we getting bencoded stuff to begin with?
|
||||||
|
// FIXME this shouldn't be necessary
|
||||||
|
message = unBencode(message);//.slice(message.indexOf(':[') + 1);
|
||||||
|
|
||||||
|
// pass the message into Chainpad
|
||||||
|
onMessage(message);
|
||||||
|
//sframeChan.query('Q_RT_MESSAGE', message, function () { });
|
||||||
|
};
|
||||||
|
|
||||||
|
// We use an object to store the webchannel so that we don't have to push new handlers to chainpad
|
||||||
|
// and remove the old ones when reconnecting and keeping the same 'realtime' object
|
||||||
|
// See realtime.onMessage below: we call wc.bcast(...) but wc may change
|
||||||
|
var wcObject = {};
|
||||||
|
var onOpen = function(wc, network, firstConnection) {
|
||||||
|
wcObject.wc = wc;
|
||||||
|
channel = wc.id;
|
||||||
|
|
||||||
|
// Add the existing peers in the userList
|
||||||
|
//TODO sframeChan.event('EV_RT_CONNECT', { myID: wc.myID, members: wc.members, readOnly: readOnly });
|
||||||
|
|
||||||
|
// Add the handlers to the WebChannel
|
||||||
|
wc.on('message', function (msg, sender) { //Channel msg
|
||||||
|
onMsg(sender, msg, wc, network);
|
||||||
|
});
|
||||||
|
wc.on('join', function (m) { onJoin(m); /*sframeChan.event('EV_RT_JOIN', m);*/ });
|
||||||
|
wc.on('leave', function (m) { onLeave(m); /*sframeChan.event('EV_RT_LEAVE', m);*/ });
|
||||||
|
|
||||||
|
if (firstConnection) {
|
||||||
|
// Sending a message...
|
||||||
|
messageFromOuter = function(message, cb) {
|
||||||
|
// Filter messages sent by Chainpad to make it compatible with Netflux
|
||||||
|
message = msgOut(message);
|
||||||
|
if (message) {
|
||||||
|
// Do not remove wcObject, it allows us to use a new 'wc' without changing the handler if we
|
||||||
|
// want to keep the same chainpad (realtime) object
|
||||||
|
try {
|
||||||
|
wcObject.wc.bcast(message).then(function() {
|
||||||
|
cb();
|
||||||
|
}, function(err) {
|
||||||
|
// The message has not been sent, display the error.
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
// Just skip calling back and it will fail on the inside.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onConnect(wc, messageFromOuter);
|
||||||
|
|
||||||
|
// Get the channel history
|
||||||
|
if (USE_HISTORY) {
|
||||||
|
var hk;
|
||||||
|
|
||||||
|
wc.members.forEach(function (p) {
|
||||||
|
if (p.length === 16) { hk = p; }
|
||||||
|
});
|
||||||
|
network.historyKeeper = hk;
|
||||||
|
|
||||||
|
var cfg = {
|
||||||
|
validateKey: validateKey,
|
||||||
|
lastKnownHash: lastKnownHash,
|
||||||
|
owners: owners,
|
||||||
|
expire: expire,
|
||||||
|
password: password
|
||||||
|
};
|
||||||
|
var msg = ['GET_HISTORY', wc.id, cfg];
|
||||||
|
// Add the validateKey if we are the channel creator and we have a validateKey
|
||||||
|
if (hk) { network.sendto(hk, JSON.stringify(msg)); }
|
||||||
|
} else {
|
||||||
|
onRdy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*var isIntentionallyLeaving = false;
|
||||||
|
window.addEventListener("beforeunload", function () {
|
||||||
|
isIntentionallyLeaving = true;
|
||||||
|
});*/
|
||||||
|
|
||||||
|
var findChannelById = function (webChannels, channelId) {
|
||||||
|
var webChannel;
|
||||||
|
|
||||||
|
// Array.some terminates once a truthy value is returned
|
||||||
|
// best case is faster than forEach, though webchannel arrays seem
|
||||||
|
// to consistently have a length of 1
|
||||||
|
webChannels.some(function(chan) {
|
||||||
|
if(chan.id === channelId) { webChannel = chan; return true;}
|
||||||
|
});
|
||||||
|
return webChannel;
|
||||||
|
};
|
||||||
|
|
||||||
|
var connectTo = function (network, firstConnection) {
|
||||||
|
// join the netflux network, promise to handle opening of the channel
|
||||||
|
network.join(channel || null).then(function(wc) {
|
||||||
|
onOpen(wc, network, firstConnection);
|
||||||
|
}, function(error) {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
network.on('disconnect', function (reason) {
|
||||||
|
console.log('disconnect');
|
||||||
|
//if (isIntentionallyLeaving) { return; }
|
||||||
|
if (reason === "network.disconnect() called") { return; }
|
||||||
|
onDisconnect();
|
||||||
|
//sframeChan.event('EV_RT_DISCONNECT');
|
||||||
|
});
|
||||||
|
|
||||||
|
network.on('reconnect', function () {
|
||||||
|
initializing = true;
|
||||||
|
connectTo(network, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
network.on('message', function (msg, sender) { // Direct message
|
||||||
|
var wchan = findChannelById(network.webChannels, channel);
|
||||||
|
if (wchan) {
|
||||||
|
onMsg(sender, msg, wchan, network, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectTo(network, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: start
|
||||||
|
/*function (config) {
|
||||||
|
config.sframeChan.whenReg('EV_RT_READY', function () {
|
||||||
|
start(config);
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,37 @@
|
|||||||
|
@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/avatar.less';
|
||||||
|
|
||||||
|
|
||||||
|
.toolbar_main();
|
||||||
|
.fileupload_main();
|
||||||
|
.alertify_main();
|
||||||
|
|
||||||
|
// body
|
||||||
|
&.cp-app-worker {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
|
||||||
|
#cp-toolbar {
|
||||||
|
display: flex; // We need this to remove a 3px border at the bottom of the toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-cryptpad-toolbar {
|
||||||
|
padding: 0px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cp-app-worker-container {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-flow: column;
|
||||||
|
padding: 20px;
|
||||||
|
align-items: center;
|
||||||
|
background-color: lighten(@colortheme_todo-bg, 15%);
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue