Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
commit
28cb40d7ee
@ -1,77 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
||||||
<script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
|
|
||||||
<style>
|
|
||||||
html, body{
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
textarea{
|
|
||||||
position: absolute;
|
|
||||||
top: 5vh;
|
|
||||||
left: 0px;
|
|
||||||
border: 0px;
|
|
||||||
|
|
||||||
padding-top: 15px;
|
|
||||||
width: 100%;
|
|
||||||
height: 95vh;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100vh;
|
|
||||||
|
|
||||||
font-size: 30px;
|
|
||||||
background-color: #073642;
|
|
||||||
color: #839496;
|
|
||||||
|
|
||||||
overflow-x: hidden;
|
|
||||||
|
|
||||||
/* disallow textarea resizes */
|
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea[disabled] {
|
|
||||||
background-color: #275662;
|
|
||||||
color: #637476;
|
|
||||||
}
|
|
||||||
|
|
||||||
#panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
right: 0px;
|
|
||||||
width: 100%;
|
|
||||||
height: 5vh;
|
|
||||||
z-index: 95;
|
|
||||||
background-color: #777;
|
|
||||||
/* min-height: 75px; */
|
|
||||||
}
|
|
||||||
#run {
|
|
||||||
display: block;
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
width: 10vw;
|
|
||||||
z-index: 100;
|
|
||||||
line-height: 5vw;
|
|
||||||
font-size: 1.5em;
|
|
||||||
background-color: #222;
|
|
||||||
color: #CCC;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 5%;
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<textarea></textarea>
|
|
||||||
<div id="panel">
|
|
||||||
<!-- TODO update this element when new users join -->
|
|
||||||
<span id="users"></span>
|
|
||||||
<!-- what else should go in the panel? -->
|
|
||||||
<a href="#" id="run">RUN</a>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,161 +0,0 @@
|
|||||||
define([
|
|
||||||
'jquery',
|
|
||||||
'/api/config',
|
|
||||||
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
|
||||||
'/bower_components/chainpad-crypto/crypto.js',
|
|
||||||
'/bower_components/textpatcher/TextPatcher.amd.js',
|
|
||||||
'/common/cryptpad-common.js'
|
|
||||||
], function ($, Config, Realtime, Crypto, TextPatcher, Cryptpad) {
|
|
||||||
|
|
||||||
var secret = Cryptpad.getSecrets();
|
|
||||||
|
|
||||||
var $textarea = $('textarea'),
|
|
||||||
$run = $('#run');
|
|
||||||
|
|
||||||
var module = {};
|
|
||||||
|
|
||||||
var config = {
|
|
||||||
initialState: '',
|
|
||||||
websocketURL: Config.websocketURL,
|
|
||||||
channel: secret.channel,
|
|
||||||
crypto: Crypto.createEncryptor(secret.key),
|
|
||||||
};
|
|
||||||
var initializing = true;
|
|
||||||
|
|
||||||
var setEditable = function (bool) { $textarea.attr('disabled', !bool); };
|
|
||||||
var canonicalize = function (text) { return text.replace(/\r\n/g, '\n'); };
|
|
||||||
|
|
||||||
setEditable(false);
|
|
||||||
|
|
||||||
var onInit = config.onInit = function (info) {
|
|
||||||
window.location.hash = info.channel + secret.key;
|
|
||||||
$(window).on('hashchange', function() { window.location.reload(); });
|
|
||||||
};
|
|
||||||
|
|
||||||
var onRemote = config.onRemote = function (info) {
|
|
||||||
if (initializing) { return; }
|
|
||||||
|
|
||||||
var userDoc = info.realtime.getUserDoc();
|
|
||||||
var current = canonicalize($textarea.val());
|
|
||||||
|
|
||||||
var op = TextPatcher.diff(current, userDoc);
|
|
||||||
|
|
||||||
var elem = $textarea[0];
|
|
||||||
|
|
||||||
var selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
|
|
||||||
return TextPatcher.transformCursor(elem[attr], op);
|
|
||||||
});
|
|
||||||
|
|
||||||
$textarea.val(userDoc);
|
|
||||||
elem.selectionStart = selects[0];
|
|
||||||
elem.selectionEnd = selects[1];
|
|
||||||
|
|
||||||
// TODO do something on external messages
|
|
||||||
// http://webdesign.tutsplus.com/tutorials/how-to-display-update-notifications-in-the-browser-tab--cms-23458
|
|
||||||
};
|
|
||||||
|
|
||||||
var onReady = config.onReady = function (info) {
|
|
||||||
module.patchText = TextPatcher.create({
|
|
||||||
realtime: info.realtime
|
|
||||||
// logging: true
|
|
||||||
});
|
|
||||||
initializing = false;
|
|
||||||
setEditable(true);
|
|
||||||
$textarea.val(info.realtime.getUserDoc());
|
|
||||||
};
|
|
||||||
|
|
||||||
var onAbort = config.onAbort = function (info) {
|
|
||||||
setEditable(false);
|
|
||||||
window.alert("Server Connection Lost");
|
|
||||||
};
|
|
||||||
|
|
||||||
var onLocal = config.onLocal = function () {
|
|
||||||
if (initializing) { return; }
|
|
||||||
module.patchText(canonicalize($textarea.val()));
|
|
||||||
};
|
|
||||||
|
|
||||||
var rt = window.rt = Realtime.start(config);
|
|
||||||
|
|
||||||
var splice = function (str, index, chars) {
|
|
||||||
var count = chars.length;
|
|
||||||
return str.slice(0, index) + chars + str.slice((index -1) + count);
|
|
||||||
};
|
|
||||||
|
|
||||||
var setSelectionRange = function (input, start, end) {
|
|
||||||
if (input.setSelectionRange) {
|
|
||||||
input.focus();
|
|
||||||
input.setSelectionRange(start, end);
|
|
||||||
} else if (input.createTextRange) {
|
|
||||||
var range = input.createTextRange();
|
|
||||||
range.collapse(true);
|
|
||||||
range.moveEnd('character', end);
|
|
||||||
range.moveStart('character', start);
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var setCursor = function (el, pos) {
|
|
||||||
setSelectionRange(el, pos, pos);
|
|
||||||
};
|
|
||||||
|
|
||||||
var state = {};
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
$textarea.on('keydown', function (e) {
|
|
||||||
// track when control keys are pushed down
|
|
||||||
//switch (e.key) { }
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
$textarea.on('keyup', function (e) {
|
|
||||||
// track when control keys are released
|
|
||||||
});
|
|
||||||
|
|
||||||
//$textarea.on('change', onLocal);
|
|
||||||
$textarea.on('keypress', function (e) {
|
|
||||||
onLocal();
|
|
||||||
switch (e.key) {
|
|
||||||
case 'Tab':
|
|
||||||
// insert a tab wherever the cursor is...
|
|
||||||
var start = $textarea.prop('selectionStart');
|
|
||||||
var end = $textarea.prop('selectionEnd');
|
|
||||||
if (typeof start !== 'undefined') {
|
|
||||||
if (start === end) {
|
|
||||||
$textarea.val(function (i, val) {
|
|
||||||
return splice(val, start, "\t");
|
|
||||||
});
|
|
||||||
setCursor($textarea[0], start +1);
|
|
||||||
} else {
|
|
||||||
// indentation?? this ought to be fun.
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// simulate a keypress so the event goes through..
|
|
||||||
// prevent default behaviour for tab
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
onLocal();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
['cut', 'paste', 'change', 'keyup', 'keydown', 'select', 'textInput']
|
|
||||||
.forEach(function (evt) {
|
|
||||||
$textarea.on(evt, onLocal);
|
|
||||||
});
|
|
||||||
|
|
||||||
$run.click(function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var content = $textarea.val();
|
|
||||||
|
|
||||||
try {
|
|
||||||
eval(content); // jshint ignore:line
|
|
||||||
} catch (err) {
|
|
||||||
// FIXME don't use alert, make an errorbox
|
|
||||||
window.alert(err.message);
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue