53 changed files with 420 additions and 734 deletions
Split View
Diff Options
-
2.jshintrc
-
9customize.dist/main.js
-
6customize.dist/messages.js
-
26customize.dist/share/frame.js
-
8customize.dist/share/test.js
-
10rpc.js
-
5storage/file.js
-
2www/assert/main.js
-
2www/common/clipboard.js
-
18www/common/common-hash.js
-
8www/common/common-history.js
-
14www/common/common-interface.js
-
24www/common/common-util.js
-
11www/common/credential.js
-
10www/common/cryptget.js
-
114www/common/cryptpad-common.js
-
10www/common/cursor.js
-
4www/common/encode.js
-
70www/common/fileObject.js
-
7www/common/fsStore.js
-
8www/common/login.js
-
6www/common/mergeDrive.js
-
2www/common/modes.js
-
6www/common/notify.js
-
11www/common/rpc.js
-
2www/common/treesome.js
-
51www/common/userObject.js
-
6www/common/visible.js
-
83www/drive/main.js
-
8www/examples/board/board.js
-
23www/examples/board/main.js
-
20www/examples/form/main.js
-
2www/examples/form/ula.js
-
77www/examples/hack/index.html
-
161www/examples/hack/main.js
-
9www/examples/json/main.js
-
4www/examples/pin/main.js
-
2www/examples/read/main.js
-
12www/examples/render/main.js
-
14www/examples/style/main.js
-
14www/examples/text/main.js
-
15www/file/main.js
-
7www/login/main.js
-
16www/media/main.js
-
2www/pad/links.js
-
42www/pad/main.js
-
48www/poll/main.js
-
24www/poll/render.js
-
10www/register/main.js
-
19www/settings/main.js
-
43www/slide/main.js
-
27www/slide/slide.js
-
20www/whiteboard/main.js
@ -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); |
|||
} |
|||
}); |
|||
}); |
|||
Write
Preview
Loading…
Cancel
Save