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>
|
<center>
|
||||||
<h1>About</h1>
|
<h1 data-localization="about">About</h1>
|
||||||
</center>
|
</center>
|
||||||
|
|
||||||
<p data-localization="main_p2"><!-- CkEditor, CodeMirror, Chainpad --></p>
|
<p data-localization="main_p2"><!-- CkEditor, CodeMirror, Chainpad --></p>
|
||||||
|
|
||||||
<h2 id="howitworks" data-localization="main_howitworks"></h2>
|
<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>
|
<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/ -->
|
<!-- 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>
|
|
||||||
|
|