Merge branch 'newtoolbar' into staging
@ -0,0 +1,5 @@
|
||||
data
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
.git
|
||||
.gitignore
|
@ -0,0 +1,4 @@
|
||||
VERSION=latest
|
||||
USE_SSL=true
|
||||
STORAGE='./storage/file'
|
||||
LOG_TO_STDOUT=true
|
@ -0,0 +1,43 @@
|
||||
FROM ubuntu:16.04
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
vim \
|
||||
wget \
|
||||
git \
|
||||
curl \
|
||||
npm \
|
||||
nodejs-legacy
|
||||
|
||||
ARG VERSION=0.3.0
|
||||
|
||||
# Download stable version
|
||||
# RUN wget https://github.com/xwiki-labs/cryptpad/archive /${VERSION}.tar.gz -O /cryptpad.tar.gz \
|
||||
# && mkdir -p /cryptpad \
|
||||
# && tar -xzf /cryptpad.tar.gz -C /cryptpad --strip-components=1 \
|
||||
# && rm /cryptpad.tar.gz
|
||||
|
||||
# Download from github
|
||||
# RUN git clone https://github.com/xwiki-labs/cryptpad.git
|
||||
|
||||
# Add code directly
|
||||
ADD . /cryptpad
|
||||
|
||||
WORKDIR /cryptpad
|
||||
|
||||
RUN npm install \
|
||||
&& npm install -g bower \
|
||||
&& bower install --allow-root
|
||||
|
||||
ADD container-start.sh /container-start.sh
|
||||
RUN chmod u+x /container-start.sh
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
VOLUME /cryptpad/datastore
|
||||
VOLUME /cryptpad/customize
|
||||
|
||||
ENV USE_SSL=false
|
||||
ENV STORAGE='./storage/file'
|
||||
ENV LOG_TO_STDOUT=true
|
||||
|
||||
CMD /container-start.sh
|
@ -1,61 +0,0 @@
|
||||
'use strict'
|
||||
let WebSocketServer = require('ws').Server
|
||||
const UNSUPPORTED_DATA = 1007
|
||||
const POLICY_VIOLATION = 1008
|
||||
const CLOSE_UNSUPPORTED = 1003
|
||||
|
||||
var run = module.exports.run = function(server) {
|
||||
server.on('connection', (socket) => {
|
||||
if(socket.upgradeReq.url !== '/cryptpad_webrtc') { return; }
|
||||
socket.on('message', (data) => {
|
||||
try {
|
||||
let msg = JSON.parse(data)
|
||||
console.log(msg)
|
||||
if (msg.hasOwnProperty('key')) {
|
||||
for (let master of server.clients) {
|
||||
if (master.key === msg.key) {
|
||||
socket.close(POLICY_VIOLATION, 'The key already exists')
|
||||
return
|
||||
}
|
||||
}
|
||||
socket.key = msg.key
|
||||
socket.joiningClients = []
|
||||
} else if (msg.hasOwnProperty('id')) {
|
||||
for (let index in socket.joiningClients) {
|
||||
if (index == msg.id) {
|
||||
socket.joiningClients[index].send(JSON.stringify({data: msg.data}))
|
||||
return
|
||||
}
|
||||
}
|
||||
socket.close(POLICY_VIOLATION, 'Unknown id')
|
||||
} else if (msg.hasOwnProperty('join')) {
|
||||
for (let master of server.clients) {
|
||||
if (master.key === msg.join) {
|
||||
socket.master = master
|
||||
master.joiningClients.push(socket)
|
||||
let id = master.joiningClients.length - 1
|
||||
master.send(JSON.stringify({id, data: msg.data}))
|
||||
return
|
||||
}
|
||||
}
|
||||
socket.close(POLICY_VIOLATION, 'Unknown key')
|
||||
} else if (msg.hasOwnProperty('data') && socket.hasOwnProperty('master')) {
|
||||
let id = socket.master.joiningClients.indexOf(socket)
|
||||
socket.master.send(JSON.stringify({id, data: msg.data}))
|
||||
} else {
|
||||
socket.close(UNSUPPORTED_DATA, 'Unsupported message format')
|
||||
}
|
||||
} catch (event) {
|
||||
socket.close(CLOSE_UNSUPPORTED, 'Server accepts only JSON')
|
||||
}
|
||||
})
|
||||
|
||||
socket.on('close', (event) => {
|
||||
if (socket.hasOwnProperty('joiningClients')) {
|
||||
for (let client of socket.joiningClients) {
|
||||
client.close(POLICY_VIOLATION, 'The peer is no longer available')
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Creating customize folder
|
||||
mkdir -p customize
|
||||
[[ ! "$(ls -A customize)" ]] && echo "Creating customize folder" \
|
||||
&& cp -R customize.dist/* customize/ \
|
||||
&& cp config.js.dist customize/config.js
|
||||
|
||||
# Linking config.js
|
||||
[[ ! -h config.js ]] && echo "Linking config.js" && ln -s customize/config.js config.js
|
||||
|
||||
# Configure
|
||||
[[ -n "$USE_SSL" ]] && echo "Using secure websockets: $USE_SSL" \
|
||||
&& sed -i "s/useSecureWebsockets: .*/useSecureWebsockets: ${USE_SSL},/g" customize/config.js
|
||||
|
||||
[[ -n "$USE_SSL" ]] && echo "Using storage adapter: $STORAGE" \
|
||||
&& sed -i "s/storage: .*/storage: ${STORAGE},/g" customize/config.js
|
||||
|
||||
[[ -n "$LOG_TO_STDOUT" ]] && echo "Logging to stdout: $LOG_TO_STDOUT" \
|
||||
&& sed -i "s/logToStdout: .*/logToStdout: ${LOG_TO_STDOUT},/g" customize/config.js
|
||||
|
||||
|
||||
exec node ./server.js
|
@ -0,0 +1,69 @@
|
||||
# Cryptpad Docker Image
|
||||
|
||||
- Configuration via .env file
|
||||
- Ready for use with traffic
|
||||
- Using github master for now, release 0.3.0 too old
|
||||
- Creating customize folder
|
||||
- Adding config.js to customize folder
|
||||
- Persistance for datastore and customize folder
|
||||
|
||||
## TODO
|
||||
|
||||
```
|
||||
cryptpad_1 | Linking config.js
|
||||
cryptpad_1 | Using secure websockets: true
|
||||
cryptpad_1 | Using storage adapter: './storage/file'
|
||||
cryptpad_1 | sed: -e expression #1, char 27: unknown option to `s'
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Set configurations Dockerfile or in .env (using docker-compose) file.
|
||||
|
||||
- VERSION=latest
|
||||
- USE_SSL=false
|
||||
- STORAGE='./storage/file'
|
||||
- LOG_TO_STDOUT=true
|
||||
|
||||
The .env variables are read by docker-compose and forwarded to docker container.
|
||||
On runtime, in `bin/container-start.sh` the settings are written to the `config.js` file.
|
||||
|
||||
## Run
|
||||
|
||||
With docker
|
||||
|
||||
```
|
||||
docker build -t xwiki/cryptpad .
|
||||
docker -d --name cryptpad -p 3000:3000 -v ${PWD}/data:/cryptpad/datastore xwiki/cryptpad
|
||||
```
|
||||
|
||||
With docker-compose
|
||||
|
||||
```
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
|
||||
## Persistance
|
||||
|
||||
The docker-compose file is preconfigured to persist folders
|
||||
|
||||
- cryptpad/datastore --> ./data/customize
|
||||
- cryptpad/customize --> ./data/customize
|
||||
|
||||
In customize included find your configuration in `config.js`.
|
||||
|
||||
The data folder is ignored by git, so if you want to add your customizations to git versioning change the volume:
|
||||
|
||||
```
|
||||
./customize:/cryptpad/customize:rw
|
||||
```
|
||||
|
||||
## SSL Proxy
|
||||
|
||||
The [traefik](https://traefik.io/) proxy has builtin Let'sEncrypt for easy SSL setup.
|
||||
In the docker-compose file you can find preset lables for usage with traefik.
|
||||
|
||||
[Traefik Docker Image](https://hub.docker.com/_/traefik/)
|
||||
|
||||
Alternativly just use plain old nginx.
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
globals define
|
||||
*/
|
||||
define([
|
||||
'/customize/languageSelector.js',
|
||||
'/customize/messages.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js'
|
||||
], function (LS, Messages) {
|
||||
var $ = window.jQuery;
|
||||
var main = function () {
|
||||
var url = window.location.pathname;
|
||||
var isHtml = /\.html/.test(url) || url === '/' || url === '';
|
||||
if (!isHtml) {
|
||||
Messages._applyTranslation();
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html',
|
||||
success: function (ret) {
|
||||
var $bar = $(ret);
|
||||
$('body').append($bar);
|
||||
|
||||
var $sel = $bar.find('#language-selector');
|
||||
|
||||
Object.keys(Messages._languages).forEach(function (code) {
|
||||
$sel.append($('<option>', {
|
||||
value: code,
|
||||
}).text(Messages._languages[code]));
|
||||
});
|
||||
|
||||
LS.main();
|
||||
Messages._applyTranslation();
|
||||
}
|
||||
});
|
||||
};
|
||||
return {
|
||||
main: main
|
||||
};
|
||||
});
|
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 256 KiB |
After Width: | Height: | Size: 307 KiB |
@ -0,0 +1,71 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="cp">
|
||||
<head>
|
||||
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="stylesheet" type="text/css" href="/customize/main.css" />
|
||||
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
|
||||
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script>
|
||||
<script src="/bower_components/requirejs/require.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
waitSeconds: 60,
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body class="html">
|
||||
<div id="cryptpadTopBar">
|
||||
<span>
|
||||
<a class="gotoMain" href="/">
|
||||
<img src="customize/cryptofist_mini.png" class="cryptpad-logo" alt="" /> CryptPad
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<!--<span class="slogan" data-localization="main_slogan"></span>-->
|
||||
|
||||
<span id="language-selector" class="right dropdown-bar"></span>
|
||||
<span class="right">
|
||||
<a href="/about.html" data-localization="about">About</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/privacy.html" data-localization="privacy">Privacy</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/terms.html" data-localization="terms">ToS</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/contact.html" data-localization="contact">Contact</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<center>
|
||||
<noscript>
|
||||
<p>
|
||||
<strong>OOPS</strong> In order to do encryption in your browser, Javascript is really <strong>really</strong> required.
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
<strong>OUPS</strong> Afin de pouvoir réaliser le chiffrement dans votre navigateur, Javascript est <strong>vraiment</strong> nécessaire.
|
||||
</p>
|
||||
</noscript>
|
||||
</center>
|
||||
|
||||
|
||||
|
||||
<div id="main_other">
|
||||
<center>
|
||||
<h1 data-localization="contact">Contact</h1>
|
||||
</center>
|
||||
|
||||
<p data-localization="main_about_p2"><!-- Contact us--></p>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 49 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 6.5 KiB |
@ -1,10 +1,11 @@
|
||||
<div id="main_other">
|
||||
<center>
|
||||
<h1>About</h1>
|
||||
<h1 data-localization="about">About</h1>
|
||||
</center>
|
||||
|
||||
<p data-localization="main_p2"><!-- CkEditor, CodeMirror, Chainpad --></p>
|
||||
|
||||
<h2 id="howitworks" data-localization="main_howitworks"></h2>
|
||||
<p data-localization="main_howitworks_p1"><!-- Operational transform, Nakamoto blockchain, server kept unaware of the content--></p>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
<div id="main_other">
|
||||
<center>
|
||||
<h1 data-localization="contact">Contact</h1>
|
||||
</center>
|
||||
|
||||
<p data-localization="main_about_p2"><!-- Contact us--></p>
|
||||
</div>
|
||||
|
@ -1,3 +1,3 @@
|
||||
<a data-localization-title="github_ribbon" href="https://github.com/xwiki-labs/cryptpad" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="position: absolute; top: 0; border: 0; left: 0; transform: scale(-1, 1);" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
<a data-localization-title="github_ribbon" href="https://github.com/xwiki-labs/cryptpad" class="github-corner" aria-label="View source on Github"><svg width="80" height="80" viewBox="0 0 250 250" style="position: absolute; top: 50px; border: 0; left: 0; transform: scale(-1, 1);z-index:2;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
|
||||
<!-- Thanks! http://tholman.com/github-corners/ -->
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
<div id="cryptpadTopBar">
|
||||
<span>
|
||||
<a class="gotoMain" href="/">
|
||||
<img src="customize/cryptofist_mini.png" class="cryptpad-logo" alt="" /> CryptPad
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<!--<span class="slogan" data-localization="main_slogan"></span>-->
|
||||
|
||||
<span id="language-selector" class="right dropdown-bar"></span>
|
||||
<span class="right">
|
||||
<a href="/about.html" data-localization="about">About</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/privacy.html" data-localization="privacy">Privacy</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/terms.html" data-localization="terms">ToS</a>
|
||||
</span>
|
||||
<span class="right">
|
||||
<a href="/contact.html" data-localization="contact">Contact</a>
|
||||
</span>
|
||||
</div>
|
@ -0,0 +1,91 @@
|
||||
|
||||
/* The container <div> - needed to position the dropdown content */
|
||||
.dropdown-bar {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.dropbtn {
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.dropbtn {
|
||||
}
|
||||
}
|
||||
|
||||
.fa {
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
|
||||
button {
|
||||
.fa-caret-down{
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-bar-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 200px;
|
||||
box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.2);
|
||||
z-index: 1000;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
&.left {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
display: block;
|
||||
}
|
||||
|
||||
a {
|
||||
color: black;
|
||||
padding: 5px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
float: none;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background-color: #f1f1f1;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 5px 0px;
|
||||
height: 1px;
|
||||
background: #bbb;
|
||||
}
|
||||
|
||||
p {
|
||||
min-width: 160px;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
white-space: normal;
|
||||
text-align: left;
|
||||
&.cryptpad-dropdown-users {
|
||||
text-align:baseline;
|
||||
.yourself, .anonymous, .viewer {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background-color: #EEEEEE;
|
||||
padding: 5px 0px;
|
||||
margin: 5px 0px;
|
||||
font-size: 16px;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
@import "./variables.less";
|
||||
|
||||
#cryptpadTopBar {
|
||||
background: @topbar-back;
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: @topbar-height;
|
||||
color: @topbar-color;
|
||||
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
font-size: 30px;
|
||||
|
||||
&> 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: #558;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
font-size: 20px;
|
||||
margin: 0px 10px;
|
||||
line-height: 40px;
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
font-size: 0.75em;
|
||||
color: #558;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: #000;
|
||||
}
|
||||
/* text-align: center;
|
||||
min-width: 100px;
|
||||
font-weight: bold;
|
||||
height: 70px;
|
||||
padding: 0 10px;
|
||||
line-height: 70px;
|
||||
display: inline-block;
|
||||
color: @topbar-button-color;*/
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
version: '2'
|
||||
services:
|
||||
|
||||
cryptpad:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- VERSION=${VERSION}
|
||||
image: "xwiki/cryptpad:${VERSION}"
|
||||
hostname: cryptpad
|
||||
|
||||
labels:
|
||||
- traefik.port=3000
|
||||
- traefik.frontend.passHostHeader=true
|
||||
environment:
|
||||
- USE_SSL=${USE_SSL}
|
||||
- STORAGE=${STORAGE}
|
||||
- LOG_TO_STDOUT=${LOG_TO_STDOUT}
|
||||
|
||||
restart: always
|
||||
volumes:
|
||||
- ./data/files:/cryptpad/datastore:rw
|
||||
- ./data/customize:/cryptpad/customize:rw
|
@ -1,58 +0,0 @@
|
||||
# This is Cryptpad
|
||||
|
||||
There are quite a few realtime editors packed into this installation.
|
||||
Most are prototypes that could use a lot of work.
|
||||
|
||||
All editors make use of Cryptpad's end to end encryption.
|
||||
Some of them have much better UI.
|
||||
|
||||
## /pad/
|
||||
|
||||
Pad is the main feature of Cryptpad. It features a CKEditor for realtime WYSIWYG editing.
|
||||
|
||||
## /code/
|
||||
|
||||
Code has syntax highlighting features.
|
||||
|
||||
## /sheet/
|
||||
|
||||
Sheet is under development. It will feature realtime collaborative spreadsheets.
|
||||
|
||||
## /text/
|
||||
|
||||
Text is a very simple encrypted plain text editor with no highlighting.
|
||||
|
||||
## /render/
|
||||
|
||||
Render takes advantage of the fact that multiple editors can both use the same 'channel' at once.
|
||||
Channel, in this sense, refers to part of the unique hash of a page which groups messages together.
|
||||
If you visit a /text/ and a /render/ page simultaneously, the changes you make in /text/ will be
|
||||
rendered as markdown in /render/. You can't edit in /render/ directly, but it adds value to other
|
||||
editors by allowing a realtime preview of your work.
|
||||
|
||||
## /vdom/
|
||||
|
||||
Vdom is under heavy development, and features an alternative approach to the realtime WYSIWYG
|
||||
editor. It syncs a representation of a virtual-dom instead of syncing the HTML itself. In practice,
|
||||
this means that there are fewer inconsistencies between different browsers' representations of the dom.
|
||||
This makes the codebase much simpler, and eliminates many classes of bugs. It's still far from perfect,
|
||||
but it is quite promising.
|
||||
|
||||
## /hack/
|
||||
|
||||
Hack leaves it to the user to decide whether XSS (Cross site scripting) is a bug or a feature.
|
||||
It exposes a realtime text pad to multiple users, and provides a button which will cause the
|
||||
contents of the pad to be passed to an `eval` call. Anyone with the hash of the page can edit
|
||||
the contents, so make sure you read the code you're about to run. If you can't read it, you
|
||||
probably shouldn't run it. In any case, it might be useful for pair programming or when you want
|
||||
to sketch out and prototype simple demos.
|
||||
|
||||
## Coming soon
|
||||
|
||||
* style
|
||||
- live editing of CSS as applied to some Lorum Ipsum
|
||||
* polyweb
|
||||
- a multi-featured editor which connects to multiple channels at once, for:
|
||||
1. live rendered markdown
|
||||
2. live style editing
|
||||
3. live javascript
|
@ -0,0 +1,390 @@
|
||||
/* PAGE */
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-size: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
.unselectable {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.app-container {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
.fa {
|
||||
/*min-width: 17px;*/
|
||||
margin-right: 3px;
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 0px;
|
||||
}
|
||||
li {
|
||||
padding: 0px 5px;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.folder,
|
||||
.file {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.contextMenu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
}
|
||||
.contextMenu li {
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
.droppable {
|
||||
background-color: #FE9A2E;
|
||||
color: #222;
|
||||
}
|
||||
.selected {
|
||||
border: 1px dotted #bbb;
|
||||
background: #666;
|
||||
color: #eee;
|
||||
margin: -1px;
|
||||
}
|
||||
span.fa-folder,
|
||||
span.fa-folder-open {
|
||||
color: #FEDE8B;
|
||||
text-shadow: -1px 0 #000000, 0 1px #000000, 1px 0 #000000, 0 -1px #000000;
|
||||
}
|
||||
/* TREE */
|
||||
#tree {
|
||||
border-right: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
background: #ffffff;
|
||||
overflow: auto;
|
||||
resize: horizontal;
|
||||
width: 250px;
|
||||
white-space: nowrap;
|
||||
max-width: 500px;
|
||||
min-width: 200px;
|
||||
padding: 10px 0px;
|
||||
color: #000000;
|
||||
}
|
||||
#tree li {
|
||||
cursor: auto;
|
||||
}
|
||||
#tree li:hover > span.element {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#tree li.collapsed ul {
|
||||
display: none;
|
||||
}
|
||||
#tree li input {
|
||||
width: calc(70%);
|
||||
}
|
||||
#tree span.element {
|
||||
cursor: pointer;
|
||||
}
|
||||
#tree .active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#tree .category2 {
|
||||
margin-top: 2em;
|
||||
}
|
||||
#tree .category2 .root > .fa {
|
||||
min-width: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#tree .fa.expcol {
|
||||
margin-left: -10px;
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
left: -20px;
|
||||
top: 9px;
|
||||
width: auto;
|
||||
height: 11px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: white;
|
||||
z-index: 10;
|
||||
cursor: default;
|
||||
}
|
||||
#tree .fa.expcol:before {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
#tree ul {
|
||||
margin: 0px 0px 0px 10px;
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
}
|
||||
#tree ul li {
|
||||
position: relative;
|
||||
}
|
||||
#tree ul li:before {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: -0.25em;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid #888888;
|
||||
height: 1em;
|
||||
border-bottom: 1px solid #888888;
|
||||
width: 17.5px;
|
||||
}
|
||||
#tree ul li:after {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
bottom: -7px;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid #888888;
|
||||
height: 100%;
|
||||
}
|
||||
#tree ul li.root {
|
||||
margin: 0px 0px 0px -10px;
|
||||
}
|
||||
#tree ul li.root:before {
|
||||
display: none;
|
||||
}
|
||||
#tree ul li.root:after {
|
||||
display: none;
|
||||
}
|
||||
#tree ul li:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
/* CONTENT */
|
||||
#content {
|
||||
box-sizing: border-box;
|
||||
background: #ffffff;
|
||||
color: #000000;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
#content h1 {
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#content .info-box {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left: 10px;
|
||||
margin: 10px auto;
|
||||
background: #ddddff;
|
||||
border: 1px solid #bbbbbb;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#content .info-box span {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
float: right;
|
||||
}
|
||||
#content li:not(.header) *:not(input) {
|
||||
pointer-events: none;
|
||||
}
|
||||
#content li:not(.header):hover .name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#content div.grid {
|
||||
padding: 20px;
|
||||
}
|
||||
#content div.grid li {
|
||||
display: inline-block;
|
||||
margin: 10px 10px;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
#content div.grid li .name {
|
||||
width: 100%;
|
||||
}
|
||||
#content div.grid li input {
|
||||
width: 100%;
|
||||
}
|
||||
#content div.grid li .fa {
|
||||
display: block;
|
||||
margin: auto;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
#content div.grid li .fa.listonly {
|
||||
display: none;
|
||||
}
|
||||
#content div.grid .listElement {
|
||||
display: none;
|
||||
}
|
||||
#content .list ul {
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
#content .list li {
|
||||
display: table-row;
|
||||
}
|
||||
#content .list li > span {
|
||||
padding: 0 5px;
|
||||
display: table-cell;
|
||||
}
|
||||
#content .list li.header {
|
||||
cursor: default;
|
||||
color: #555555;
|
||||
}
|
||||
#content .list li.header span:not(.fa) {
|
||||
text-align: left;
|
||||
}
|
||||
#content .list li.header span.sortasc,
|
||||
#content .list li.header span.sortdesc {
|
||||
float: right;
|
||||
}
|
||||
#content .list li.header > span {
|
||||
padding: 15px 5px;
|
||||
}
|
||||
#content .list li.header > span.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
#content .list li.header > span.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
#content .list li.header > span.clickable:hover {
|
||||
background: #e8e8e8;
|
||||
}
|
||||
#content .list .element span {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#content .list .element span.icon {
|
||||
width: 30px;
|
||||
}
|
||||
#content .list .element span.type,
|
||||
#content .list .element span.atime,
|
||||
#content .list .element span.ctime {
|
||||
width: 175px;
|
||||
}
|
||||
#content .list .element span.title {
|
||||
width: 250px;
|
||||
}
|
||||
@media screen and (max-width: 1200px) {
|
||||
#content .list .element span.title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
#content .list .element span.folders,
|
||||
#content .list .element span.files {
|
||||
width: 150px;
|
||||
}
|
||||
.parentFolder {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
}
|
||||
.parentFolder:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#folderContent {
|
||||
padding-right: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
/* Toolbar */
|
||||
#driveToolbar {
|
||||
background: #dddddd;
|
||||
color: #555555;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
border-top: 1px solid #cccccc;
|
||||
border-bottom: ;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
z-index: 100;
|
||||
box-sizing: content-box;
|
||||
/* The container <div> - needed to position the dropdown content */
|
||||
}
|
||||
#driveToolbar .newPadContainer {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
#driveToolbar button.element {
|
||||
border-radius: 2px;
|
||||
height: 30px;
|
||||
background: #888888;
|
||||
color: #eeeeee;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
#driveToolbar button.element:hover {
|
||||
box-shadow: 0px 0px 2px #000;
|
||||
}
|
||||
#driveToolbar button.new {
|
||||
padding: 0 20px;
|
||||
}
|
||||
#driveToolbar .dropdown-bar {
|
||||
margin: 5px 5px;
|
||||
line-height: 1em;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
#driveToolbar .dropdown-bar.right {
|
||||
float: right;
|
||||
/* Right-side buttons */
|
||||
}
|
||||
#driveToolbar .dropdown-bar.right button {
|
||||
display: inline-block;
|
||||
}
|
||||
#driveToolbar .dropdown-bar.right button.active {
|
||||
display: none;
|
||||
}
|
||||
#driveToolbar .dropdown-bar.right button .fa {
|
||||
margin-right: 0px;
|
||||
}
|
||||
#driveToolbar .dropdown-bar-content {
|
||||
margin-top: -3px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
#driveToolbar .leftside {
|
||||
width: 250px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#driveToolbar .rightside {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
}
|
||||
#driveToolbar .path {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
line-height: 40px;
|
||||
cursor: default;
|
||||
}
|
||||
#driveToolbar .path .element {
|
||||
padding: 5px;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
#driveToolbar .path .element.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
#driveToolbar .path .element.clickable:hover {
|
||||
background: #ffffff;
|
||||
border: 1px solid #888888;
|
||||
}
|
@ -0,0 +1,454 @@
|
||||
@tree-bg: #fff;
|
||||
@tree-fg: #000;
|
||||
@tree-lines-col: #888;
|
||||
|
||||
@content-bg: @tree-bg;
|
||||
@content-fg: @tree-fg;
|
||||
@info-box-bg: #ddddff;
|
||||
@info-box-border: #bbb;
|
||||
@table-header-fg: #555;
|
||||
@table-header-bg: #e8e8e8;
|
||||
|
||||
@toolbar-bg: #ddd;
|
||||
@toolbar-fg: #555;
|
||||
@toolbar-border-col: #ccc;
|
||||
@toolbar-button-bg: #888;
|
||||
@toolbar-button-fg: #eee;
|
||||
@toolbar-path-bg: #fff;
|
||||
@toolbar-path-border: #888;
|
||||
|
||||
/* PAGE */
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-size: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.unselectable {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
.fa {
|
||||
/*min-width: 17px;*/
|
||||
margin-right: 3px;
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 0px; // Remove the default padding
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 0px 5px;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.folder, .file {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.contextMenu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
li {
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.droppable {
|
||||
background-color: #FE9A2E;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.selected {
|
||||
border: 1px dotted #bbb;
|
||||
background: #666;
|
||||
color: #eee;
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
span {
|
||||
&.fa-folder, &.fa-folder-open {
|
||||
color: #FEDE8B;
|
||||
text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
|
||||
}
|
||||
}
|
||||
|
||||
/* TREE */
|
||||
|
||||
|
||||
#tree {
|
||||
border-right: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
background: @tree-bg;
|
||||
overflow: auto;
|
||||
resize: horizontal;
|
||||
width: 250px;
|
||||
white-space: nowrap;
|
||||
max-width: 500px;
|
||||
min-width: 200px;
|
||||
padding: 10px 0px;
|
||||
color: @tree-fg;
|
||||
li {
|
||||
cursor: auto;
|
||||
&:hover > span.element {
|
||||
text-decoration: underline;
|
||||
}
|
||||
&.collapsed ul {
|
||||
display: none;
|
||||
}
|
||||
input {
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
}
|
||||
span.element {
|
||||
cursor: pointer;
|
||||
}
|
||||
.active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.category2 {
|
||||
margin-top: 2em;
|
||||
.root {
|
||||
&> .fa {
|
||||
min-width: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.fa.expcol {
|
||||
margin-left: -10px;
|
||||
font-size: 14px;
|
||||
position: absolute;
|
||||
left: -20px;
|
||||
top: 9px;
|
||||
width: auto;
|
||||
height: 11px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: white;
|
||||
z-index: 10;
|
||||
cursor: default;
|
||||
&:before {
|
||||
position:relative;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
// Expand/collapse lines
|
||||
ul {
|
||||
margin: 0px 0px 0px 10px;
|
||||
list-style: none;
|
||||
padding-left: 10px;
|
||||
li {
|
||||
position: relative;
|
||||
&:before {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
top: -0.25em;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid @tree-lines-col;
|
||||
height: 1em;
|
||||
border-bottom: 1px solid @tree-lines-col;
|
||||
width: 17.5px;
|
||||
}
|
||||
&:after {
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
bottom: -7px;
|
||||
content: '';
|
||||
display: block;
|
||||
border-left: 1px solid @tree-lines-col;
|
||||
height: 100%;
|
||||
}
|
||||
&.root {
|
||||
margin: 0px 0px 0px -10px;
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* CONTENT */
|
||||
|
||||
#content {
|
||||
box-sizing: border-box;
|
||||
background: @content-bg;
|
||||
color: @content-fg;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
h1 {
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.info-box {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
padding-left: 10px;
|
||||
margin: 10px auto;
|
||||
background: @info-box-bg;
|
||||
border: 1px solid @info-box-border;
|
||||
border-radius: 5px;
|
||||
span {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
li {
|
||||
&:not(.header) {
|
||||
*:not(input) {
|
||||
pointer-events: none;
|
||||
}
|
||||
&:hover {
|
||||
.name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
div.grid {
|
||||
padding: 20px;
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 10px 10px;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
|
||||
.name {
|
||||
width: 100%;
|
||||
}
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
.fa {
|
||||
display: block;
|
||||
margin: auto;
|
||||
font-size: 40px;
|
||||
text-align: center;
|
||||
&.listonly {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.listElement {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
// Make it act as a table!
|
||||
ul {
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
li {
|
||||
display: table-row;
|
||||
&> span {
|
||||
padding: 0 5px;
|
||||
display: table-cell;
|
||||
}
|
||||
}
|
||||
li {
|
||||
&.header {
|
||||
cursor: default;
|
||||
color: @table-header-fg;
|
||||
span {
|
||||
&:not(.fa) {
|
||||
text-align: left;
|
||||
}
|
||||
&.sortasc, &.sortdesc {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
&> span {
|
||||
padding: 15px 5px;
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: @table-header-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.element {
|
||||
span {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
box-sizing: border-box;
|
||||
&.icon {
|
||||
width: 30px;
|
||||
}
|
||||
&.type, &.atime, &.ctime {
|
||||
width: 175px;
|
||||
}
|
||||
&.title {
|
||||
width: 250px;
|
||||
@media screen and (max-width: 1200px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.folders, &.files {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.parentFolder {
|
||||
cursor: pointer;
|
||||
margin-left: 10px;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
#folderContent {
|
||||
padding-right: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
/* Toolbar */
|
||||
|
||||
#driveToolbar {
|
||||
background: @toolbar-bg;
|
||||
color: @toolbar-fg;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
border-top: 1px solid @toolbar-border-col;
|
||||
border-bottom: ;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||
z-index: 100;
|
||||
box-sizing: content-box;
|
||||
|
||||
.newPadContainer {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
&.element {
|
||||
border-radius: 2px;
|
||||
height: 30px;
|
||||
background: @toolbar-button-bg;
|
||||
color: @toolbar-button-fg;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
font-weight: bold;
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 2px #000;
|
||||
}
|
||||
}
|
||||
&.new {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
/* The container <div> - needed to position the dropdown content */
|
||||
.dropdown-bar {
|
||||
margin: 5px 5px;
|
||||
line-height: 1em;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
&.right {
|
||||
float: right;
|
||||
/* Right-side buttons */
|
||||
button {
|
||||
display: inline-block;
|
||||
&.active {
|
||||
display: none;
|
||||
}
|
||||
.fa {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dropdown-bar-content {
|
||||
margin-top: -3px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.leftside {
|
||||
width: 250px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.rightside {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
flex: 1;
|
||||
}
|
||||
.path {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
line-height: 40px;
|
||||
cursor: default;
|
||||
.element {
|
||||
padding: 5px;
|
||||
border: 1px solid @toolbar-bg;
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
&.clickable {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
background: @toolbar-path-bg;
|
||||
border: 1px solid @toolbar-path-border;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<!--
|
||||
|
||||
This file only exists for supporting some old URLs that we're trying not to break.
|
||||
|
||||
Legacy support is tricky.
|
||||
|
||||
:(
|
||||
|
||||
-->
|
||||
<script>
|
||||
(function () {
|
||||
if (/cryptpad\.fr$/i.test(window.location.hostname)) {
|
||||
window.location.hostname = 'old.cryptpad.fr';
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>There's nothing here.</p>
|
||||
<p>You probably want to visit <strong><a href="https://old.cryptpad.fr">old.cryptpad.fr</a></strong></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|