Base for Drive in sandboxed iframe

pull/1/head
yflory 7 years ago
parent a1c124f1be
commit 456370b1aa

@ -22,11 +22,12 @@ html.cp-app-print {
.app-print_main();
}
body.cp-app-drive { @import "../../../newdrive/app-drive.less"; }
body.cp-app-pad { @import "../../../pad/app-pad.less"; }
body.cp-app-code { @import "../../../code/app-code.less"; }
body.cp-app-slide { @import "../../../slide/app-slide.less"; }
body.cp-app-file { @import "../../../file/app-file.less"; }
body.cp-app-filepicker { @import "../../../filepicker/app-filepicker.less"; }
body.cp-app-poll { @import "../../../poll/app-poll.less"; }
//body.cp-app-poll { @import "../../../poll/app-poll.less"; }
body.cp-app-whiteboard { @import "../../../whiteboard/app-whiteboard.less"; }

@ -2,7 +2,7 @@
<html class="cp-app-noscroll">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/code/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/code/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }

@ -245,7 +245,7 @@ define([
stopListening(listener);
cb();
});
listener = listenForKeys(close, close);
listener = listenForKeys(close, close, ok);
var $ok = $(ok).click(close);
document.body.appendChild(frame);
@ -294,7 +294,7 @@ define([
$ok.click();
}, function () { // no
$cancel.click();
});
}, input);
document.body.appendChild(frame);
setTimeout(function () {

@ -73,7 +73,6 @@ define(['json.sortify'], function (Sortify) {
});
};
console.log('here register');
sframeChan.on('EV_METADATA_UPDATE', function (ev) {
meta = ev;
if (ev.priv) {

@ -42,6 +42,25 @@ var afterLoaded = function (req) {
updated: updated,
cache: data.cache
};
data.localStore = data.localStore || {};
var lsUpdated = {};
window.cryptpadStore = {
get: function (k, cb) {
setTimeout(function () { cb(data.localStore[k]); });
},
getAll: function (cb) {
setTimeout(function () {
cb(JSON.parse(JSON.stringify(data.localStore)));
});
},
put: function (k, v, cb) {
cb = cb || function () { };
lsUpdated[k] = v;
setTimeout(function () { data.localStore[k] = v; cb(); });
},
updated: lsUpdated,
store: data.localStore
};
window.cryptpadLanguage = data.language;
require(['/common/sframe-boot2.js'], function () { });
};

@ -51,9 +51,7 @@ define([
$('<td>').text(Messages.cancel).appendTo($thead);
var createTableContainer = function ($body) {
console.log($body);
File.$container = $('<div>', { id: 'cp-fileupload' }).append($table).appendTo($body);
console.log('done');
return File.$container;
};

@ -1,12 +1,14 @@
define([
'jquery',
'/api/config',
'/common/cryptpad-common.js',
'/common/common-util.js',
'/common/media-tag.js',
'/common/tippy.min.js',
'/customize/application_config.js',
'css!/common/tippy.css',
], function ($, Cryptpad, MediaTag, Tippy, AppConfig) {
], function ($, Config, Cryptpad, Util, MediaTag, Tippy, AppConfig) {
var UI = {};
var Messages = Cryptpad.Messages;
@ -292,6 +294,103 @@ define([
}
};
/* Create a usage bar which keeps track of how much storage space is used
by your CryptDrive. The getPinnedUsage RPC is one of the heavier calls,
so we throttle its usage. Clients will not update more than once per
LIMIT_REFRESH_RATE. It will be update at least once every three such intervals
If changes are made to your drive in the interim, they will trigger an
update.
*/
var LIMIT_REFRESH_RATE = 30000; // milliseconds
UI.createUsageBar = function (common, cb) {
if (!common.isLoggedIn()) { return cb("NOT_LOGGED_IN"); }
// getPinnedUsage updates common.account.usage, and other values
// so we can just use those and only check for errors
var $container = $('<span>', {'class':'limit-container'});
var todo;
var updateUsage = Cryptpad.notAgainForAnother(function () {
common.getPinUsage(todo);
}, LIMIT_REFRESH_RATE);
todo = function (err, data) {
if (err) { return void console.error(err); }
var usage = data.usage;
var limit = data.limit;
var plan = data.plan;
$container.html('');
var unit = Util.magnitudeOfBytes(limit);
var usage = unit === 'GB'? Util.bytesToGigabytes(usage):
Util.bytesToMegabytes(usage);
var limit = unit === 'GB'? Util.bytesToGigabytes(limit):
Util.bytesToMegabytes(limit);
var $limit = $('<span>', {'class': 'cryptpad-limit-bar'}).appendTo($container);
var quota = usage/limit;
var $usage = $('<span>', {'class': 'usage'}).css('width', quota*100+'%');
var makeDonateButton = function () {
$('<a>', {
'class': 'upgrade btn btn-success',
href: Cryptpad.donateURL,
rel: "noreferrer noopener",
target: "_blank",
}).text(Messages.supportCryptpad).appendTo($container);
};
var makeUpgradeButton = function () {
$('<a>', {
'class': 'upgrade btn btn-success',
href: Cryptpad.upgradeURL,
rel: "noreferrer noopener",
target: "_blank",
}).text(Messages.upgradeAccount).appendTo($container);
};
if (!Config.removeDonateButton) {
if (!common.isLoggedIn() || !Config.allowSubscriptions) {
// user is not logged in, or subscriptions are disallowed
makeDonateButton();
} else if (!plan) {
// user is logged in and subscriptions are allowed
// and they don't have one. show upgrades
makeUpgradeButton();
} else {
// they have a plan. show nothing
}
}
var prettyUsage;
var prettyLimit;
if (unit === 'GB') {
prettyUsage = Messages._getKey('formattedGB', [usage]);
prettyLimit = Messages._getKey('formattedGB', [limit]);
} else {
prettyUsage = Messages._getKey('formattedMB', [usage]);
prettyLimit = Messages._getKey('formattedMB', [limit]);
}
if (quota < 0.8) { $usage.addClass('normal'); }
else if (quota < 1) { $usage.addClass('warning'); }
else { $usage.addClass('above'); }
var $text = $('<span>', {'class': 'usageText'});
$text.text(usage + ' / ' + prettyLimit);
$limit.append($usage).append($text);
};
setInterval(function () {
updateUsage();
}, LIMIT_REFRESH_RATE * 3);
updateUsage();
/*getProxy().on('change', ['drive'], function () {
updateUsage();
}); TODO*/
cb(null, $container);
};
UI.createUserAdminMenu = function (Common, config) {
var metadataMgr = Common.getMetadataMgr();

@ -44,14 +44,21 @@ define([
localStorage.CRYPTPAD_URLARGS = ApiConfig.requireConf.urlArgs;
}
var cache = {};
var localStore = {};
Object.keys(localStorage).forEach(function (k) {
if (k.indexOf('CRYPTPAD_CACHE|') !== 0) { return; }
if (k.indexOf('CRYPTPAD_CACHE|') === 0) {
cache[k.slice(('CRYPTPAD_CACHE|').length)] = localStorage[k];
return;
}
if (k.indexOf('CRYPTPAD_STORE|') === 0) {
localStore[k.slice(('CRYPTPAD_STORE|').length)] = localStorage[k];
return;
}
});
SFrameChannel.create($('#sbox-iframe')[0].contentWindow, waitFor(function (sfc) {
sframeChan = sfc;
}), false, { cache: cache, language: Cryptpad.getLanguage() });
}), false, { cache: cache, localStore: localStore, language: Cryptpad.getLanguage() });
Cryptpad.ready(waitFor());
}));
}).nThen(function (waitFor) {
@ -61,8 +68,17 @@ define([
localStorage['CRYPTPAD_CACHE|' + k] = x[k];
});
});
sframeChan.on('EV_LOCALSTORE_PUT', function (x) {
Object.keys(x).forEach(function (k) {
if (typeof(x[k]) === "undefined") {
delete localStorage['CRYPTPAD_STORE|' + k];
return;
}
localStorage['CRYPTPAD_STORE|' + k] = x[k];
});
});
secret = Cryptpad.getSecrets();
secret = cfg.getSecrets ? cfg.getSecrets(Cryptpad) : Cryptpad.getSecrets();
if (!secret.channel) {
// New pad: create a new random channel id
secret.channel = Cryptpad.createChannelId();
@ -384,6 +400,15 @@ define([
Cryptpad.resetTags(null, data);
});
sframeChan.on('Q_PIN_GET_USAGE', function (data, cb) {
Cryptpad.isOverPinLimit(function (err, overLimit, data) {
cb({
error: err,
data: data
});
});
});
if (cfg.addRpc) {
cfg.addRpc(sframeChan, Cryptpad);
}
@ -397,7 +422,7 @@ define([
CpNfOuter.start({
sframeChan: sframeChan,
channel: secret.channel,
network: Cryptpad.getNetwork(),
network: cfg.newNetwork || Cryptpad.getNetwork(),
validateKey: secret.keys.validateKey || undefined,
readOnly: readOnly,
crypto: Crypto.createEncryptor(secret.keys),
@ -409,7 +434,7 @@ define([
});
return;
}
if (readOnly) { return; }
if (readOnly || cfg.noHash) { return; }
Cryptpad.replaceHash(Cryptpad.getEditHashFromKeys(wc.id, secret.keys));
}
});

@ -77,6 +77,7 @@ define([
funcs.openTemplatePicker = callWithCommon(UI.openTemplatePicker);
funcs.displayAvatar = callWithCommon(UI.displayAvatar);
funcs.createButton = callWithCommon(UI.createButton);
funcs.createUsageBar = callWithCommon(UI.createUsageBar);
// History
funcs.getHistory = callWithCommon(History.create);
@ -156,6 +157,12 @@ define([
if (cb) { cb(data); }
});
};
funcs.getPinUsage = function (cb) {
cb = cb || $.noop;
ctx.sframeChan.query('Q_PIN_GET_USAGE', null, function (err, data) {
cb(err || data.error, data.data);
});
};
funcs.isOverPinLimit = function (cb) {
ctx.sframeChan.query('Q_GET_PIN_LIMIT_STATUS', null, function (err, data) {
@ -283,6 +290,18 @@ define([
ctx.sframeChan.event('EV_CACHE_PUT', x);
};
});
ctx.sframeChan.whenReg('EV_LOCALSTORE_PUT', function () {
if (Object.keys(window.cryptpadStore.updated).length) {
ctx.sframeChan.event('EV_LOCALSTORE_PUT', window.cryptpadStore.updated);
}
window.cryptpadStore._put = window.cryptpadStore.put;
window.cryptpadStore.put = function (k, v, cb) {
window.cryptpadStore._put(k, v, cb);
var x = {};
x[k] = v;
ctx.sframeChan.event('EV_LOCALSTORE_PUT', x);
};
});
UI.addTooltips();

@ -67,6 +67,9 @@ define({
// Use anonymous rpc from inside the iframe (for avatars & pin usage).
'Q_ANON_RPC_MESSAGE': true,
// Get the user's pin limit, usage and plan
'Q_PIN_GET_USAGE': true,
// Check the pin limit to determine if we can store the pad in the drive or if we should.
// display a warning
'Q_GET_PIN_LIMIT_STATUS': true,
@ -129,7 +132,10 @@ define({
'EV_PRESENT_URL_SET_VALUE': true,
// Put one or more entries to the cache which will go in localStorage.
// Cache is wiped after each new release
'EV_CACHE_PUT': true,
// Put one or more entries to the localStore which will go in localStorage.
'EV_LOCALSTORE_PUT': true,
// Set and get the tags using the tag prompt button
'Q_TAGS_GET': true,

@ -487,6 +487,7 @@ define([
files[FILES_DATA][id] = data;
cb(null, id);
};
// TODO
if (!Cryptpad.isLoggedIn() || !AppConfig.enablePinning || config.testMode) {
return void todo();
}
@ -585,6 +586,7 @@ define([
// ADD
var add = exp.add = function (id, path) {
// TODO
if (!Cryptpad.isLoggedIn() && !config.testMode) { return; }
var data = files[FILES_DATA][id];
if (!data || typeof(data) !== "object") { return; }
@ -624,6 +626,7 @@ define([
exp.forget = function (href) {
var id = getIdFromHref(href);
if (!id) { return; }
// TODO
if (!Cryptpad.isLoggedIn() && !config.testMode) {
// delete permanently
exp.removePadAttribute(href);
@ -653,6 +656,7 @@ define([
};
var checkDeletedFiles = function () {
// Nothing in OLD_FILES_DATA for workgroups
// TODO
if (workgroup || (!Cryptpad.isLoggedIn() && !config.testMode)) { return; }
var filesList = getFiles([ROOT, 'hrefArray', TRASH]);
@ -680,6 +684,7 @@ define([
var trashPaths = paths.filter(function(x) { return isPathIn(x, [TRASH]); });
var allFilesPaths = paths.filter(function(x) { return isPathIn(x, [FILES_DATA]); });
// TODO
if (!Cryptpad.isLoggedIn() && !config.testMode) {
allFilesPaths.forEach(function (path) {
var el = find(path);
@ -855,6 +860,7 @@ define([
}
try {
debug("Migrating file system...");
// TODO
Cryptpad.feedback('Migrate-oldFilesData', true);
files.migrate = 1;
var next = function () {
@ -904,6 +910,7 @@ define([
};
if (exp.rt) {
exp.rt.sync();
// TODO
Cryptpad.whenRealtimeSyncs(exp.rt, next);
} else {
window.setTimeout(next, 1000);
@ -1079,6 +1086,7 @@ define([
migrateAttributes(el, id, parsed);
// TODO
if ((Cryptpad.isLoggedIn() || config.testMode) && rootFiles.indexOf(id) === -1) {
debug("An element in filesData was not in ROOT, TEMPLATE or TRASH.", id, el);
var newName = Cryptpad.createChannelId();

@ -2,7 +2,7 @@
<html class="cp-app-noscroll">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/file/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/file/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }

@ -2,7 +2,7 @@
<html style="height: 100%; background: transparent;">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/filepicker/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/filepicker/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
body #cp-loading {

@ -0,0 +1,879 @@
@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';
.toolbar_main();
.fileupload_main();
.alertify_main();
@import (once) "../../customize/src/less/variables.less";
@import (once) "../../customize/src/less/mixins.less";
@tree-bg: #eee;
@tree-fg: #000;
@tree-lines-col: #888;
@drive-hover: #eee;
@drive-hover-light: lighten(@drive-hover, 20%);
@content-bg: #fff;
@content-bg-ro: darken(@content-bg, 10%);
@content-fg: @tree-fg;
@info-box-bg: #d2e1f2;
@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-border: #888;
@toolbar-button-bg-hover: #777;
@toolbar-button-fg: #eee;
@toolbar-path-bg: #fff;
@toolbar-path-border: #888;
@size-mobile: 600px;
/* PAGE */
display: flex;
flex-flow: column;
max-height: 100%;
min-height: auto;
// TODO: pin limit in a separate file, less2
/* Pin limit */
.limit-container {
@toolbar-green: #5cb85c;
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;
}
}
img.icon {
max-width: 20px;
max-height: 16px;
}
.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;
@media screen and (max-width: @size-mobile) {
display: block;
#driveToolbar {
.path .element {
display: none;
}
}
#tree {
resize: none;
width: 100%;
max-width: unset;
max-height: unset;
border-bottom: 1px solid @toolbar-border-col;
.category {
margin-top: 0.5em;
}
}
}
}
.padColor { color: @toolbar-pad-bg; }
.codeColor { color: @toolbar-code-bg; }
.slideColor { color: @toolbar-slide-bg; }
.pollColor { color: @toolbar-poll-bg; }
.fileColor { color: @toolbar-file-bg; }
.whiteboardColor { color: @toolbar-whiteboard-bg; }
.driveColor { color: @toolbar-drive-bg; }
.defaultColor { color: @toolbar-default-bg; }
div:focus {
outline: none;
}
.fa {
font-family: FontAwesome;
}
ul {
list-style: none;
padding-left: 0px; // Remove the default padding
}
li {
padding: 0px 5px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.contextMenu {
display: none;
position: absolute;
z-index: 500;
li {
padding: 0;
font-size: @main-font-size;
a {
cursor: pointer;
}
}
}
.droppable {
background-color: #FE9A2E;
color: #222;
}
.selected {
background: #666 !important;
color: #eee;
margin: -1px;
.fa-minus-square-o, .fa-plus-square-o {
color: @tree-fg;
}
}
.selectedTmp {
border: 1px dotted #bbb;
background: #AAA;
color: #ddd;
margin: -1px;
.fa-minus-square-o, .fa-plus-square-o {
color: @tree-fg;
}
}
span {
&.fa-folder, &.fa-folder-open {
//color: #FEDE8B;
//text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
}
/* TREE */
#tree {
font-size: @main-font-size;
//border-right: 1px solid #ccc;
box-sizing: border-box;
background: @tree-bg;
overflow: auto;
resize: horizontal;
width: auto;
white-space: nowrap;
max-width: 500px;
min-width: 200px;
padding: 0px;
color: @tree-fg;
display: flex;
flex-flow: column;
max-height: 100%;
.categories-container {
flex: 1;
max-width: 500px;
overflow: auto;
}
img.icon {
margin-bottom: 3px;
margin-left: -2px;
}
.docTree {
margin-top: 20px;
//padding: 0 0 0 20px;
padding: 0;
cursor: auto;
&li, li {
padding: 0;
&.collapsed ul {
display: none;
}
input {
width: ~"calc(100% - 30px)";
padding: 0 10px;
border: 0;
color: lighten(@tree-fg, 40%);
}
& > span.element-row {
overflow: hidden;
text-overflow: ellipsis;
//min-width: ~"calc(100% + 5px)";
.leftsideCategory();
width: ~"calc(100% + 5px)";
margin: 0;
margin-bottom: -6px;
display: inline-block;
cursor: pointer;
margin-left: -5px;
padding-left: 5px;
}
& > span.element-row:not(.selected):not(.active):hover {
//background-color: @drive-hover;
}
}
}
span.element {
cursor: pointer;
}
/*.active {
&:not(.selected):not(.droppable) {
background-color: darken(@drive-hover, 15%);
}
}*/
.category {
margin: 0;
margin-top: 15px;
.root {
&> .fa {
min-width: 30px;
cursor: pointer;
}
}
li {
padding: 0;
.element-row {
display: block;
padding-left: 20px;
.leftsideCategory();
margin: 0;
.fa {
width: 25px;
}
}
}
}
.category:last-child {
margin-bottom: 20px;
}
#allfilesTree {
margin-top: 0;
}
.limit-container {
margin-top: 0;
}
#searchContainer {
text-align: center;
padding: 0;
position: relative;
input {
background: lighten(@toolbar-drive-bg, 8%);
color: @toolbar-drive-color;
.placeholderColor(@toolbar-drive-color);
outline-width: 0px;
border-radius: 0;
width: 100%;
//border: 1px solid #ccc;
border: 0;
border-right: 1px solid lighten(@toolbar-drive-bg, 16%);
//border-right: 0;
height: @toolbar-line-height;
padding: 0 5px;
padding-left: 45px;
&:focus {
outline-width: 0px;
}
}
.searchIcon {
color: @toolbar-drive-color;
position: absolute;
left: 20px; // TODO align with drive categories
top: 8px;
}
}
.fa.expcol {
margin-left: -10px;
font-size: 14px;
position: absolute;
left: -20px;
top: 10px;
width: 11px !important;
height: 11px !important;
padding: 0;
margin: 0;
background: white;
z-index: 10;
cursor: default;
&:before {
position:relative;
top: -1px;
}
}
.docTree {
.root > .element-row > .expcol {
position: relative;
top:0;
left: -10px;
}
.root > .element-row > .folder {
margin-left: -5px;
}
.root {
&> .element-row {
padding-left: 20px;
}
&> ul {
padding-left: 30px;
}
}
}
// Expand/collapse lines
.docTree ul {
margin: 0px 0px 0px 10px;
list-style: none;
padding-left: 10px;
li {
position: relative;
&:before {
position: absolute;
left: -15px;
top: -11px;
content: '';
display: block;
border-left: 1px solid @tree-lines-col;
height: ~"calc(1em + 11px)";
border-bottom: 1px solid @tree-lines-col;
width: 15px;
}
&: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 */
#rightCol {
display: flex;
flex-flow: column;
flex: 1;
// Needed to avoid the folder's path to overflows
// https://stackoverflow.com/questions/38223879/white-space-nowrap-breaks-flexbox-layout
min-width: 0;
}
#content {
box-sizing: border-box;
background: @content-bg;
color: @content-fg;
overflow: auto;
flex: 1;
display: flex;
flex-flow: column;
position: relative;
.selectBox {
display: none;
background-color: rgba(100, 100, 100, 0.7);
position: absolute;
z-index: 50;
}
&.readonly {
background: @content-bg-ro;
}
h1 {
padding-left: 10px;
margin-top: 10px;
}
.info-box {
line-height: 2em;
padding: 0.25em 0.75em;
margin: 1em;
background: @info-box-bg;
span {
cursor: pointer;
float: right;
margin-top: 0.5em;
}
&.noclose {
}
}
li {
cursor: default;
&:not(.header) {
*:not(input) {
/*pointer-events: none;*/
}
&:hover {
&:not(.selected, .selectedTmp) {
background-color: @drive-hover;
}
.name {
/*text-decoration: underline;*/
}
}
}
}
#folderContent {
li {
&.searchResult {
border-bottom: 1px solid @info-box-border;
display: block;
&:hover {
background-color: initial;
}
table {
width: 100%;
.label2 {
width: 150px;
font-size: 15px;
text-align: right;
padding-right: 15px;
}
.openDir {
a {
cursor: pointer;
color: #41b7d8;
&:hover {
color: #014c8c;
text-decoration: underline;
}
}
}
.path {
font-style: italic;
direction: rtl;
.element {
display: inline-block;
margin-right: 5px;
}
}
.title {
font-weight: bold;
cursor: pointer;
&:hover {
background-color: @drive-hover;
}
}
.col2 {
width: 250px;
}
td.icon {
width: 50px;
font-size: 40px;
}
}
}
}
}
.element {
.truncated { display: none; }
}
div.grid {
padding: 20px;
.fileIcon;
li {
&.element {
position: relative;
}
input {
width: 100%;
margin-top: 5px;
}
.state {
position: absolute;
top: 3px;
right: 3px;
.fa {
margin:0;
font-size: 18px;
}
}
}
.listElement {
display: none;
}
.addpad {
cursor: pointer;
opacity: 0.5;
padding: 0;
&:hover {
opacity: 0.7;
}
.fa {
cursor: pointer;
font-size: 90px;
margin-top: 5px;
margin-bottom: 0;
}
}
}
.list {
.grid-element {
display: none;
}
// Make it act as a table!
padding-left: 20px;
ul {
display: table;
width: 100%;
padding: 0px 10px;
}
li {
display: table-row;
&> span {
padding: 0 5px;
display: table-cell;
}
&:not(.header) {
height: @toolbar-line-height;
line-height: @toolbar-line-height;
}
&.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;
&.state {
.fa:not(:last-child) {
margin-right: 5px;
}
}
&.icon, &.state {
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;
}
#addPadDialog.cp-modal-container {
.fileIcon;
li:not(.selected):hover {
border: 1px solid white;
}
.cp-modal {
display: flex;
flex-flow: column;
li, li .fa {
cursor: pointer;
}
&> p {
margin: 50px;
}
&> div {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
overflow-y: auto;
.uploadFile {
break-after: always;
page-break-after: always;
}
}
}
@media screen and (max-height: @browser_media-not-big) {
.cp-modal {
& > p {
display: none;
}
& > div {
align-content: unset;
li {
height: 40px;
width: 90%;
display: flex;
align-items: center;
.fa {
font-size: 32px;
}
.name {
height: auto;
}
}
}
}
}
}
/* Toolbar */
#driveToolbar {
background: lighten(@toolbar-drive-bg, 8%);
color: @toolbar-drive-color;
//height: 30px;
//display: flex;
//flex-flow: row;
z-index: 100;
box-sizing: border-box;
height: @toolbar-line-height;
padding: 0;
display: flex;
flex-flow: row;
* {
outline-width: 0;
&:focus {
outline-width: 0;
}
}
.newPadContainer {
display: inline-block;
height: 100%;
}
.history {
float: right;
.cp-toolbar-drawer-element {
display: none;
}
}
.rightside, .leftside {
display: inline-block;
margin: 0;
padding: 0;
.fa {
margin: 0;
}
button {
height: @toolbar-line-height;
padding: 0 10px;
border: none;
border-radius: 0;
box-sizing: border-box;
background: transparent;
font-size: @main-font-size;
color: @toolbar-drive-color;
transition: all 0.15s;
.drawer {
display: none;
}
.fa, span {
font-size: @main-font-size;
}
&:hover {
background: @toolbar-drive-bg;
}
&.active {
display: none;
}
}
}
.rightside {
float: right;
& > * {
float: right;
}
#contextButtonsContainer {
display: inline-block;
height: 100%;
}
padding-left: 10px;
}
.leftside {
& > span {
height: 100%;
margin: 0;
}
button {
padding: 0 10px;
.fa {
margin-right: 5px;
}
.cp-dropdown-button-title {
display: inline-flex;
height: @toolbar-line-height;
align-items: center;
span:not(.fa) {
line-height: 23px;
}
}
}
}
button {
font: @toolbar-button-font;
span {
font: @toolbar-button-font;
}
.fa, &.fa {
font-family: FontAwesome;
}
}
/* The container <div> - needed to position the dropdown content */
.cp-dropdown-container {
margin: 2px 2px;
line-height: 1em;
position: relative;
display: inline-block;
}
.cp-dropdown-content {
margin-right: 2px;
}
.path {
flex: 1;
width: 100%;
height: @toolbar-line-height;
line-height: @toolbar-line-height;
cursor: default;
width: auto;
overflow: hidden;
white-space: nowrap;
direction: rtl;
max-width: 100%;
text-align: left;
.element {
display: inline-block;
height: @toolbar-line-height;
line-height: @toolbar-line-height;
font-size: @main-font-size;
padding: 0 5px;
border: 0;
background: darken(@toolbar-drive-bg, 10%);
color: @toolbar-drive-color;
box-sizing: border-box;
transition: all 0.15s;
&.separator {
color: #ccc;
}
&.clickable {
cursor: pointer;
&:hover {
background: darken(@toolbar-drive-bg, 15%);
}
}
}
}
}

@ -0,0 +1,820 @@
@import "/customize/src/less/variables.less";
@import "/customize/src/less/mixins.less";
@tree-bg: #eee;
@tree-fg: #000;
@tree-lines-col: #888;
@drive-hover: #eee;
@drive-hover-light: lighten(@drive-hover, 20%);
@content-bg: #fff;
@content-bg-ro: darken(@content-bg, 10%);
@content-fg: @tree-fg;
@info-box-bg: #d2e1f2;
@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-border: #888;
@toolbar-button-bg-hover: #777;
@toolbar-button-fg: #eee;
@toolbar-path-bg: #fff;
@toolbar-path-border: #888;
@size-mobile: 600px;
/* PAGE */
html, body {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 0;
margin: 0;
position: relative;
font-size: @main-font-size;
overflow: auto;
}
body {
display: flex;
flex-flow: column;
}
img.icon {
max-width: 20px;
max-height: 16px;
}
.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;
@media screen and (max-width: @size-mobile) {
display: block;
#driveToolbar {
.path .element {
display: none;
}
}
#tree {
resize: none;
width: 100%;
max-width: unset;
max-height: unset;
border-bottom: 1px solid @toolbar-border-col;
.category {
margin-top: 0.5em;
}
}
}
}
.padColor { color: @toolbar-pad-bg; }
.codeColor { color: @toolbar-code-bg; }
.slideColor { color: @toolbar-slide-bg; }
.pollColor { color: @toolbar-poll-bg; }
.fileColor { color: @toolbar-file-bg; }
.whiteboardColor { color: @toolbar-whiteboard-bg; }
.driveColor { color: @toolbar-drive-bg; }
.defaultColor { color: @toolbar-default-bg; }
div:focus {
outline: none;
}
.fa {
font-family: FontAwesome;
}
ul {
list-style: none;
padding-left: 0px; // Remove the default padding
}
li {
padding: 0px 5px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.contextMenu {
display: none;
position: absolute;
z-index: 500;
li {
padding: 0;
font-size: @main-font-size;
a {
cursor: pointer;
}
}
}
.droppable {
background-color: #FE9A2E;
color: #222;
}
.selected {
background: #666 !important;
color: #eee;
margin: -1px;
.fa-minus-square-o, .fa-plus-square-o {
color: @tree-fg;
}
}
.selectedTmp {
border: 1px dotted #bbb;
background: #AAA;
color: #ddd;
margin: -1px;
.fa-minus-square-o, .fa-plus-square-o {
color: @tree-fg;
}
}
span {
&.fa-folder, &.fa-folder-open {
//color: #FEDE8B;
//text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;
}
}
/* TREE */
#tree {
font-size: @main-font-size;
//border-right: 1px solid #ccc;
box-sizing: border-box;
background: @tree-bg;
overflow: auto;
resize: horizontal;
width: auto;
white-space: nowrap;
max-width: 500px;
min-width: 200px;
padding: 0px;
color: @tree-fg;
display: flex;
flex-flow: column;
max-height: 100%;
.categories-container {
flex: 1;
max-width: 500px;
overflow: auto;
}
img.icon {
margin-bottom: 3px;
margin-left: -2px;
}
.docTree {
margin-top: 20px;
//padding: 0 0 0 20px;
padding: 0;
cursor: auto;
&li, li {
padding: 0;
&.collapsed ul {
display: none;
}
input {
width: ~"calc(100% - 30px)";
padding: 0 10px;
border: 0;
color: lighten(@tree-fg, 40%);
}
& > span.element-row {
overflow: hidden;
text-overflow: ellipsis;
//min-width: ~"calc(100% + 5px)";
.leftsideCategory();
width: ~"calc(100% + 5px)";
margin: 0;
margin-bottom: -6px;
display: inline-block;
cursor: pointer;
margin-left: -5px;
padding-left: 5px;
}
& > span.element-row:not(.selected):not(.active):hover {
//background-color: @drive-hover;
}
}
}
span.element {
cursor: pointer;
}
/*.active {
&:not(.selected):not(.droppable) {
background-color: darken(@drive-hover, 15%);
}
}*/
.category {
margin: 0;
margin-top: 15px;
.root {
&> .fa {
min-width: 30px;
cursor: pointer;
}
}
li {
padding: 0;
.element-row {
display: block;
padding-left: 20px;
.leftsideCategory();
margin: 0;
.fa {
width: 25px;
}
}
}
}
.category:last-child {
margin-bottom: 20px;
}
#allfilesTree {
margin-top: 0;
}
.limit-container {
margin-top: 0;
}
#searchContainer {
text-align: center;
padding: 0;
position: relative;
input {
background: lighten(@toolbar-drive-bg, 8%);
color: @toolbar-drive-color;
.placeholderColor(@toolbar-drive-color);
outline-width: 0px;
border-radius: 0;
width: 100%;
//border: 1px solid #ccc;
border: 0;
border-right: 1px solid lighten(@toolbar-drive-bg, 16%);
//border-right: 0;
height: @toolbar-line-height;
padding: 0 5px;
padding-left: 45px;
&:focus {
outline-width: 0px;
}
}
.searchIcon {
color: @toolbar-drive-color;
position: absolute;
left: 20px; // TODO align with drive categories
top: 8px;
}
}
.fa.expcol {
margin-left: -10px;
font-size: 14px;
position: absolute;
left: -20px;
top: 10px;
width: 11px !important;
height: 11px !important;
padding: 0;
margin: 0;
background: white;
z-index: 10;
cursor: default;
&:before {
position:relative;
top: -1px;
}
}
.docTree {
.root > .element-row > .expcol {
position: relative;
top:0;
left: -10px;
}
.root > .element-row > .folder {
margin-left: -5px;
}
.root {
&> .element-row {
padding-left: 20px;
}
&> ul {
padding-left: 30px;
}
}
}
// Expand/collapse lines
.docTree ul {
margin: 0px 0px 0px 10px;
list-style: none;
padding-left: 10px;
li {
position: relative;
&:before {
position: absolute;
left: -15px;
top: -11px;
content: '';
display: block;
border-left: 1px solid @tree-lines-col;
height: ~"calc(1em + 11px)";
border-bottom: 1px solid @tree-lines-col;
width: 15px;
}
&: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 */
#rightCol {
display: flex;
flex-flow: column;
flex: 1;
// Needed to avoid the folder's path to overflows
// https://stackoverflow.com/questions/38223879/white-space-nowrap-breaks-flexbox-layout
min-width: 0;
}
#content {
box-sizing: border-box;
background: @content-bg;
color: @content-fg;
overflow: auto;
flex: 1;
display: flex;
flex-flow: column;
position: relative;
.selectBox {
display: none;
background-color: rgba(100, 100, 100, 0.7);
position: absolute;
z-index: 50;
}
&.readonly {
background: @content-bg-ro;
}
h1 {
padding-left: 10px;
margin-top: 10px;
}
.info-box {
line-height: 2em;
padding: 0.25em 0.75em;
margin: 1em;
background: @info-box-bg;
span {
cursor: pointer;
float: right;
margin-top: 0.5em;
}
&.noclose {
}
}
li {
cursor: default;
&:not(.header) {
*:not(input) {
/*pointer-events: none;*/
}
&:hover {
&:not(.selected, .selectedTmp) {
background-color: @drive-hover;
}
.name {
/*text-decoration: underline;*/
}
}
}
}
#folderContent {
li {
&.searchResult {
border-bottom: 1px solid @info-box-border;
display: block;
&:hover {
background-color: initial;
}
table {
width: 100%;
.label2 {
width: 150px;
font-size: 15px;
text-align: right;
padding-right: 15px;
}
.openDir {
a {
cursor: pointer;
color: #41b7d8;
&:hover {
color: #014c8c;
text-decoration: underline;
}
}
}
.path {
font-style: italic;
direction: rtl;
.element {
display: inline-block;
margin-right: 5px;
}
}
.title {
font-weight: bold;
cursor: pointer;
&:hover {
background-color: @drive-hover;
}
}
.col2 {
width: 250px;
}
td.icon {
width: 50px;
font-size: 40px;
}
}
}
}
}
.element {
.truncated { display: none; }
}
div.grid {
padding: 20px;
.fileIcon;
li {
&.element {
position: relative;
}
input {
width: 100%;
margin-top: 5px;
}
.state {
position: absolute;
top: 3px;
right: 3px;
.fa {
margin:0;
font-size: 18px;
}
}
}
.listElement {
display: none;
}
.addpad {
cursor: pointer;
opacity: 0.5;
padding: 0;
&:hover {
opacity: 0.7;
}
.fa {
cursor: pointer;
font-size: 90px;
margin-top: 5px;
margin-bottom: 0;
}
}
}
.list {
.grid-element {
display: none;
}
// Make it act as a table!
padding-left: 20px;
ul {
display: table;
width: 100%;
padding: 0px 10px;
}
li {
display: table-row;
&> span {
padding: 0 5px;
display: table-cell;
}
&:not(.header) {
height: @toolbar-line-height;
line-height: @toolbar-line-height;
}
&.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;
&.state {
.fa:not(:last-child) {
margin-right: 5px;
}
}
&.icon, &.state {
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;
}
#addPadDialog.cp-modal-container {
.fileIcon;
li:not(.selected):hover {
border: 1px solid white;
}
.cp-modal {
display: flex;
flex-flow: column;
li, li .fa {
cursor: pointer;
}
&> p {
margin: 50px;
}
&> div {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
overflow-y: auto;
.uploadFile {
break-after: always;
page-break-after: always;
}
}
}
@media screen and (max-height: @browser_media-not-big) {
.cp-modal {
& > p {
display: none;
}
& > div {
align-content: unset;
li {
height: 40px;
width: 90%;
display: flex;
align-items: center;
.fa {
font-size: 32px;
}
.name {
height: auto;
}
}
}
}
}
}
/* Toolbar */
#driveToolbar {
background: lighten(@toolbar-drive-bg, 8%);
color: @toolbar-drive-color;
//height: 30px;
//display: flex;
//flex-flow: row;
z-index: 100;
box-sizing: border-box;
height: @toolbar-line-height;
padding: 0;
display: flex;
flex-flow: row;
* {
outline-width: 0;
&:focus {
outline-width: 0;
}
}
.newPadContainer {
display: inline-block;
height: 100%;
}
.history {
float: right;
}
.rightside, .leftside {
display: inline-block;
margin: 0;
padding: 0;
.fa {
margin: 0;
}
button {
height: @toolbar-line-height;
padding: 0 10px;
border: none;
border-radius: 0;
box-sizing: border-box;
background: transparent;
font-size: @main-font-size;
color: @toolbar-drive-color;
transition: all 0.15s;
.drawer {
display: none;
}
.fa, span {
font-size: @main-font-size;
}
&:hover {
background: @toolbar-drive-bg;
}
&.active {
display: none;
}
}
}
.rightside {
float: right;
& > * {
float: right;
}
#contextButtonsContainer {
display: inline-block;
height: 100%;
}
padding-left: 10px;
}
.leftside {
& > span {
height: 100%;
margin: 0;
}
button {
padding: 0 10px;
.fa {
margin-right: 5px;
}
.cp-dropdown-button-title {
display: inline-flex;
height: @toolbar-line-height;
align-items: center;
span:not(.fa) {
line-height: 23px;
}
}
}
}
button {
font: @toolbar-button-font;
span {
font: @toolbar-button-font;
}
.fa, &.fa {
font-family: FontAwesome;
}
}
/* The container <div> - needed to position the dropdown content */
.cp-dropdown-container {
margin: 2px 2px;
line-height: 1em;
position: relative;
display: inline-block;
}
.cp-dropdown-content {
margin-right: 2px;
}
.path {
flex: 1;
width: 100%;
height: @toolbar-line-height;
line-height: @toolbar-line-height;
cursor: default;
width: auto;
overflow: hidden;
white-space: nowrap;
direction: rtl;
max-width: 100%;
text-align: left;
.element {
display: inline-block;
height: @toolbar-line-height;
line-height: @toolbar-line-height;
font-size: @main-font-size;
padding: 0 5px;
border: 0;
background: darken(@toolbar-drive-bg, 10%);
color: @toolbar-drive-color;
box-sizing: border-box;
transition: all 0.15s;
&.separator {
color: #ccc;
}
&.clickable {
cursor: pointer;
&:hover {
background: darken(@toolbar-drive-bg, 15%);
}
}
}
}
}

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="no-referrer" />
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
html, body {
margin: 0px;
padding: 0px;
}
#sbox-iframe {
position:fixed;
top:0px;
left:0px;
bottom:0px;
right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
}
#sbox-filePicker-iframe {
position: fixed;
top:0; left:0;
bottom:0; right:0;
width:100%;
height: 100%;
border: 0;
}
</style>
</head>
<body>
<iframe id="sbox-iframe">

@ -0,0 +1,63 @@
<!DOCTYPE html>
<html class="cp-app-noscroll">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/newdrive/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }
</style>
</head>
<body class="cp-app-drive">
<div id="cp-toolbar" class="cp-toolbar-container"></div>
<div class="app-container" tabindex="0">
<div id="tree">
</div>
<div id="rightCol">
<div id="driveToolbar"></div>
<div id="content" tabindex="2"></div>
</div>
<div id="treeContextMenu" class="contextMenu dropdown clearfix unselectable">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" data-icon="fa-folder-open" class="open dropdown-item" data-localization="fc_open">Open</a></li>
<li><a tabindex="-1" data-icon="fa-eye" class="open_ro dropdown-item" data-localization="fc_open_ro">Open (read-only)</a></li>
<li><a tabindex="-1" data-icon="fa-pencil" class="rename editable dropdown-item" data-localization="fc_rename">Rename</a></li>
<li><a tabindex="-1" data-icon="fa-trash" class="delete editable dropdown-item" data-localization="fc_delete">Delete</a></li>
<li><a tabindex="-1" data-icon="fa-folder" class="newfolder editable dropdown-item" data-localization="fc_newfolder">New folder</a></li>
<li><a tabindex="-1" data-icon="fa-database" class="properties dropdown-item" data-localization="fc_prop">Properties</a></li>
</ul>
</div>
<div id="contentContextMenu" class="contextMenu dropdown clearfix unselectable">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" data-icon="fa-folder" class="newfolder editable dropdown-item" data-localization="fc_newfolder">New folder</a></li>
<li><a tabindex="-1" data-icon="fa-file-word-o" class="newdoc own editable dropdown-item" data-type="pad" data-localization="button_newpad">New pad</a></li>
<li><a tabindex="-1" data-icon="fa-file-code-o" class="newdoc own editable dropdown-item" data-type="code" data-localization="button_newcode">New code</a></li>
<li><a tabindex="-1" data-icon="fa-file-powerpoint-o" class="newdoc own editable dropdown-item" data-type="slide" data-localization="button_newslide">New slide</a></li>
<li><a tabindex="-1" data-icon="fa-calendar" class="newdoc own editable dropdown-item" data-type="poll" data-localization="button_newpoll">New poll</a></li>
<li><a tabindex="-1" data-icon="fa-paint-brush" class="newdoc own editable dropdown-item" data-type="whiteboard" data-localization="button_newwhiteboard">New whiteboard</a></li>
</ul>
</div>
<div id="defaultContextMenu" class="contextMenu dropdown clearfix unselectable">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" data-icon="fa-folder-open" class="open dropdown-item" data-localization="fc_open">Open</a></li>
<li><a tabindex="-1" data-icon="fa-eye" class="open_ro dropdown-item" data-localization="fc_open_ro">Open (read-only)</a></li>
<li><a tabindex="-1" data-icon="fa-trash" class="delete dropdown-item" data-localization="fc_delete">Delete</a></li>
<li><a tabindex="-1" data-icon="fa-database" class="properties dropdown-item" data-localization="fc_prop">Properties</a></li>
</ul>
</div>
<div id="trashTreeContextMenu" class="contextMenu dropdown clearfix unselectable">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" data-icon="fa-trash-o" class="empty editable dropdown-item" data-localization="fc_empty">Empty the trash</a></li>
</ul>
</div>
<div id="trashContextMenu" class="contextMenu dropdown clearfix unselectable">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu" style="display:block;position:static;margin-bottom:5px;">
<li><a tabindex="-1" data-icon="fa-eraser" class="remove editable dropdown-item" data-localization="fc_remove">Delete permanently</a></li>
<li><a tabindex="-1" data-icon="fa-repeat" class="restore editable dropdown-item" data-localization="fc_restore">Restore</a></li>
<li><a tabindex="-1" data-icon="fa-database" class="properties dropdown-item" data-localization="fc_prop">Properties</a></li>
</ul>
</div>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,53 @@
// Load #1, load as little as possible because we are in a race to get the loading screen up.
define([
'/bower_components/nthen/index.js',
'/api/config',
'jquery',
'/common/requireconfig.js',
'/common/sframe-common-outer.js',
'/common/cryptpad-common.js',
'/bower_components/netflux-websocket/netflux-client.js',
], function (nThen, ApiConfig, $, RequireConfig, SFCommonO, Cryptpad, Netflux) {
var requireConfig = RequireConfig();
// Loaded in load #2
nThen(function (waitFor) {
$(waitFor());
}).nThen(function (waitFor) {
var req = {
cfg: requireConfig,
req: [ '/common/loading.js' ],
pfx: window.location.origin
};
window.rc = requireConfig;
window.apiconf = ApiConfig;
$('#sbox-iframe').attr('src',
ApiConfig.httpSafeOrigin + '/newdrive/inner.html?' + requireConfig.urlArgs +
'#' + encodeURIComponent(JSON.stringify(req)));
// This is a cheap trick to avoid loading sframe-channel in parallel with the
// loading screen setup.
var done = waitFor();
var onMsg = function (msg) {
var data = JSON.parse(msg.data);
if (data.q !== 'READY') { return; }
window.removeEventListener('message', onMsg);
var _done = done;
done = function () { };
_done();
};
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
var getSecrets = function (Cryptpad) {
var hash = window.location.hash.slice(1) || Cryptpad.getUserHash() || localStorage.FS_hash;
return Cryptpad.getSecrets('drive', hash);
};
Netflux.connect(Cryptpad.getWebsocketURL()).then(function (network) {
SFCommonO.start({
getSecrets: getSecrets,
newNetwork: network,
noHash: true
});
}, function (err) { console.error(err); });
});
});

@ -2,7 +2,7 @@
<html class="cp-app-noscroll">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/pad/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/pad/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
</head>
<body class="cp-app-pad">
<textarea style="display:none" id="editor1" name="editor1"></textarea>

@ -2,7 +2,7 @@
<html class="cp-app-noscroll cp-app-print">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/slide/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/slide/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }

@ -2,7 +2,7 @@
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/whiteboard/inner.js" data-main="/common/sframe-boot.js?ver=1.5" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<script async data-bootload="/whiteboard/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
#editor1 { display: none; }

Loading…
Cancel
Save