Clean old code

pull/1/head
yflory 7 years ago
parent be848c1bec
commit 354c63bd64

@ -1,54 +0,0 @@
define([
'jquery',
'/customize/application_config.js',
'/common/cryptpad-common.js',
'/api/config',
], function ($, Config, Cryptpad, ApiConfig) {
window.APP = {
Cryptpad: Cryptpad,
};
var Messages = Cryptpad.Messages;
$(function () {
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
var $upgrade = $('#upgrade');
var showUpgrade = function (text, feedback, url) {
if (ApiConfig.removeDonateButton) { return; }
if (localStorage.plan) { return; }
if (!text) { return; }
$upgrade.text(text).show();
$upgrade.click(function () {
Cryptpad.feedback(feedback);
window.open(url,'_blank');
});
};
// User admin menu
var $userMenu = $('#user-menu');
var userMenuCfg = {
$initBlock: $userMenu,
'static': true
};
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.find('button').addClass('btn').addClass('btn-secondary');
$(window).click(function () {
$('.cp-dropdown-content').hide();
});
if (Cryptpad.isLoggedIn() && ApiConfig.allowSubscriptions) {
showUpgrade(Messages.upgradeAccount, "HOME_UPGRADE_ACCOUNT", Cryptpad.upgradeURL);
} else {
showUpgrade(Messages.supportCryptpad, "HOME_SUPPORT_CRYPTPAD", Cryptpad.donateURL);
}
});
});

@ -2,7 +2,6 @@ define([
'jquery',
'/customize/application_config.js',
'/common/cryptpad-common.js',
'/customize/header.js',
], function ($, Config, Cryptpad) {
window.APP = {

@ -1,308 +0,0 @@
define([
'jquery',
'/common/modes.js',
'/common/themes.js',
'/bower_components/file-saver/FileSaver.min.js'
], function ($, Modes, Themes) {
var saveAs = window.saveAs;
var module = {};
module.create = function (ifrw, Cryptpad, defaultMode, CMeditor) {
var exp = {};
var Messages = Cryptpad.Messages;
var CodeMirror = exp.CodeMirror = CMeditor;
CodeMirror.modeURL = "cm/mode/%N/%N";
var $pad = $('#pad-iframe');
var $textarea = exp.$textarea = $('#editor1');
if (!$textarea.length) { $textarea = exp.$textarea = $pad.contents().find('#editor1'); }
var Title;
var onLocal = function () {};
var $rightside;
var $drawer;
exp.init = function (local, title, toolbar) {
if (typeof local === "function") {
onLocal = local;
}
Title = title;
$rightside = toolbar.$rightside;
$drawer = toolbar.$drawer;
};
var editor = exp.editor = CMeditor.fromTextArea($textarea[0], {
lineNumbers: true,
lineWrapping: true,
autoCloseBrackets: true,
matchBrackets : true,
showTrailingSpace : true,
styleActiveLine : true,
search: true,
highlightSelectionMatches: {showToken: /\w+/},
extraKeys: {"Shift-Ctrl-R": undefined},
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
mode: defaultMode || "javascript",
readOnly: true
});
editor.setValue(Messages.codeInitialState);
var setMode = exp.setMode = function (mode, cb) {
exp.highlightMode = mode;
if (mode !== "text") {
CMeditor.autoLoadMode(editor, mode);
}
editor.setOption('mode', mode);
if (exp.$language) {
var name = exp.$language.find('a[data-value="' + mode + '"]').text() || undefined;
name = name ? Messages.languageButton + ' ('+name+')' : Messages.languageButton;
exp.$language.setValue(mode, name);
}
if(cb) { cb(mode); }
};
var setTheme = exp.setTheme = (function () {
var path = '/common/theme/';
var $head = $(ifrw.document.head);
var themeLoaded = exp.themeLoaded = function (theme) {
return $head.find('link[href*="'+theme+'"]').length;
};
var loadTheme = exp.loadTheme = function (theme) {
$head.append($('<link />', {
rel: 'stylesheet',
href: path + theme + '.css',
}));
};
return function (theme, $select) {
if (!theme) {
editor.setOption('theme', 'default');
} else {
if (!themeLoaded(theme)) {
loadTheme(theme);
}
editor.setOption('theme', theme);
}
if ($select) {
var name = theme || undefined;
name = name ? Messages.themeButton + ' ('+theme+')' : Messages.themeButton;
$select.setValue(theme, name);
}
};
}());
exp.getHeadingText = function () {
var lines = editor.getValue().split(/\n/);
var text = '';
lines.some(function (line) {
// lines including a c-style comment are also valuable
var clike = /^\s*(\/\*|\/\/)(.*)?(\*\/)*$/;
if (clike.test(line)) {
line.replace(clike, function (a, one, two) {
if (!(two && two.replace)) { return; }
text = two.replace(/\*\/\s*$/, '').trim();
});
return true;
}
// lisps?
var lispy = /^\s*(;|#\|)+(.*?)$/;
if (lispy.test(line)) {
line.replace(lispy, function (a, one, two) {
text = two;
});
return true;
}
// lines beginning with a hash are potentially valuable
// works for markdown, python, bash, etc.
var hash = /^#+(.*?)$/;
if (hash.test(line)) {
line.replace(hash, function (a, one) {
text = one;
});
return true;
}
// TODO make one more pass for multiline comments
});
return text.trim();
};
exp.configureLanguage = function (cb, onModeChanged) {
var options = [];
Modes.list.forEach(function (l) {
options.push({
tag: 'a',
attributes: {
'data-value': l.mode,
'href': '#',
},
content: l.language // Pretty name of the language value
});
});
var dropdownConfig = {
text: 'Mode', // Button initial text
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
isSelect: true,
feedback: 'CODE_LANGUAGE',
};
var $block = exp.$language = Cryptpad.createDropdown(dropdownConfig);
$block.find('button').attr('title', Messages.languageButtonTitle);
$block.find('a').click(function () {
setMode($(this).attr('data-value'), onModeChanged);
onLocal();
});
if ($drawer) { $drawer.append($block); }
if (cb) { cb(); }
};
exp.configureTheme = function (cb) {
/* Remember the user's last choice of theme using localStorage */
var themeKey = 'CRYPTPAD_CODE_THEME';
var lastTheme = localStorage.getItem(themeKey) || 'default';
var options = [];
Themes.forEach(function (l) {
options.push({
tag: 'a',
attributes: {
'data-value': l.name,
'href': '#',
},
content: l.name // Pretty name of the language value
});
});
var dropdownConfig = {
text: 'Theme', // Button initial text
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
isSelect: true,
initialValue: lastTheme,
feedback: 'CODE_THEME',
};
var $block = exp.$theme = Cryptpad.createDropdown(dropdownConfig);
$block.find('button').attr('title', Messages.themeButtonTitle);
setTheme(lastTheme, $block);
$block.find('a').click(function () {
var theme = $(this).attr('data-value');
setTheme(theme, $block);
localStorage.setItem(themeKey, theme);
});
if ($drawer) { $drawer.append($block); }
if (cb) { cb(); }
};
exp.exportText = function () {
var text = editor.getValue();
var ext = Modes.extensionOf(exp.highlightMode);
var title = Cryptpad.fixFileName(Title ? Title.suggestTitle('cryptpad') : "?") + (ext || '.txt');
Cryptpad.prompt(Messages.exportPrompt, title, function (filename) {
if (filename === null) { return; }
var blob = new Blob([text], {
type: 'text/plain;charset=utf-8'
});
saveAs(blob, filename);
});
};
exp.importText = function (content, file) {
var $bar = ifrw.$('#cme_toolbox');
var mode;
var mime = CodeMirror.findModeByMIME(file.type);
if (!mime) {
var ext = /.+\.([^.]+)$/.exec(file.name);
if (ext[1]) {
mode = CMeditor.findModeByExtension(ext[1]);
mode = mode && mode.mode || null;
}
} else {
mode = mime && mime.mode || null;
}
if (mode && Modes.list.some(function (o) { return o.mode === mode; })) {
setMode(mode);
$bar.find('#language-mode').val(mode);
} else {
console.log("Couldn't find a suitable highlighting mode: %s", mode);
setMode('text');
$bar.find('#language-mode').val('text');
}
editor.setValue(content);
onLocal();
};
var cursorToPos = function(cursor, oldText) {
var cLine = cursor.line;
var cCh = cursor.ch;
var pos = 0;
var textLines = oldText.split("\n");
for (var line = 0; line <= cLine; line++) {
if(line < cLine) {
pos += textLines[line].length+1;
}
else if(line === cLine) {
pos += cCh;
}
}
return pos;
};
var posToCursor = function(position, newText) {
var cursor = {
line: 0,
ch: 0
};
var textLines = newText.substr(0, position).split("\n");
cursor.line = textLines.length - 1;
cursor.ch = textLines[cursor.line].length;
return cursor;
};
exp.setValueAndCursor = function (oldDoc, remoteDoc, TextPatcher) {
var scroll = editor.getScrollInfo();
//get old cursor here
var oldCursor = {};
oldCursor.selectionStart = cursorToPos(editor.getCursor('from'), oldDoc);
oldCursor.selectionEnd = cursorToPos(editor.getCursor('to'), oldDoc);
editor.setValue(remoteDoc);
editor.save();
var op = TextPatcher.diff(oldDoc, remoteDoc);
var selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
return TextPatcher.transformCursor(oldCursor[attr], op);
});
if(selects[0] === selects[1]) {
editor.setCursor(posToCursor(selects[0], remoteDoc));
}
else {
editor.setSelection(posToCursor(selects[0], remoteDoc), posToCursor(selects[1], remoteDoc));
}
editor.scrollTo(scroll.left, scroll.top);
};
return exp;
};
return module;
});

@ -1,366 +0,0 @@
define([
'jquery',
'/file/file-crypto.js',
'/common/common-thumbnail.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, FileCrypto, Thumb) {
var Nacl = window.nacl;
var module = {};
var blobToArrayBuffer = module.blobToArrayBuffer = function (blob, cb) {
var reader = new FileReader();
reader.onloadend = function () {
cb(void 0, this.result);
};
reader.readAsArrayBuffer(blob);
};
var arrayBufferToString = function (AB) {
try {
return Nacl.util.encodeBase64(new Uint8Array(AB));
} catch (e) {
console.error(e);
return null;
}
};
module.upload = function (file, noStore, common, updateProgress, onComplete, onError, onPending) {
var u8 = file.blob; // This is not a blob but a uint8array
var metadata = file.metadata;
// if it exists, path contains the new pad location in the drive
var path = file.path;
var key = Nacl.randomBytes(32);
var next = FileCrypto.encrypt(u8, metadata, key);
var estimate = FileCrypto.computeEncryptedSize(u8.length, metadata);
var sendChunk = function (box, cb) {
var enc = Nacl.util.encodeBase64(box);
common.rpc.send.unauthenticated('UPLOAD', enc, function (e, msg) {
cb(e, msg);
});
};
var actual = 0;
var again = function (err, box) {
if (err) { throw new Error(err); }
if (box) {
actual += box.length;
var progressValue = (actual / estimate * 100);
updateProgress(progressValue);
return void sendChunk(box, function (e) {
if (e) { return console.error(e); }
next(again);
});
}
if (actual !== estimate) {
console.error('Estimated size does not match actual size');
}
// if not box then done
common.uploadComplete(function (e, id) {
if (e) { return void console.error(e); }
var uri = ['', 'blob', id.slice(0,2), id].join('/');
console.log("encrypted blob is now available as %s", uri);
var b64Key = Nacl.util.encodeBase64(key);
var hash = common.getFileHashFromKeys(id, b64Key);
var href = '/file/#' + hash;
var title = metadata.name;
if (noStore) { return void onComplete(href); }
common.initialPath = path;
common.renamePad(title || "", href, function (err) {
if (err) { return void console.error(err); }
onComplete(href);
common.setPadAttribute('fileType', metadata.type, null, href);
});
});
};
common.uploadStatus(estimate, function (e, pending) {
if (e) {
console.error(e);
onError(e);
return;
}
if (pending) {
return void onPending(function () {
// if the user wants to cancel the pending upload to execute that one
common.uploadCancel(function (e, res) {
if (e) {
return void console.error(e);
}
console.log(res);
next(again);
});
});
}
next(again);
});
};
module.create = function (common, config) {
var File = {};
var Messages = common.Messages;
var queue = File.queue = {
queue: [],
inProgress: false
};
var uid = function () {
return 'file-' + String(Math.random()).substring(2);
};
var $table = File.$table = $('<table>', { id: 'uploadStatus' });
var $thead = $('<tr>').appendTo($table);
$('<td>').text(Messages.upload_name).appendTo($thead);
$('<td>').text(Messages.upload_size).appendTo($thead);
$('<td>').text(Messages.upload_progress).appendTo($thead);
$('<td>').text(Messages.cancel).appendTo($thead);
var createTableContainer = function ($body) {
File.$container = $('<div>', { id: 'uploadStatusContainer' }).append($table).appendTo($body);
return File.$container;
};
var getData = function (file, href) {
var data = {};
data.name = file.metadata.name;
data.url = href;
if (file.metadata.type.slice(0,6) === 'image/') {
data.mediatag = true;
}
return data;
};
var upload = function (file) {
var blob = file.blob; // This is not a blob but an array buffer
var u8 = new Uint8Array(blob);
var metadata = file.metadata;
var id = file.id;
if (queue.inProgress) { return; }
queue.inProgress = true;
var $row = $table.find('tr[id="'+id+'"]');
$row.find('.upCancel').html('-');
var $pv = $row.find('.progressValue');
var $pb = $row.find('.progressContainer');
var $pc = $row.find('.upProgress');
var $link = $row.find('.upLink');
var updateProgress = function (progressValue) {
$pv.text(Math.round(progressValue*100)/100 + '%');
$pb.css({
width: (progressValue/100)*$pc.width()+'px'
});
};
var onComplete = function (href) {
$link.attr('href', href)
.click(function (e) {
e.preventDefault();
window.open($link.attr('href'), '_blank');
});
var title = metadata.name;
common.log(Messages._getKey('upload_success', [title]));
common.prepareFeedback('upload')();
if (config.onUploaded) {
var data = getData(file, href);
config.onUploaded(file.dropEvent, data);
}
queue.inProgress = false;
queue.next();
};
var onError = function (e) {
queue.inProgress = false;
queue.next();
if (e === 'TOO_LARGE') {
// TODO update table to say too big?
return void common.alert(Messages.upload_tooLarge);
}
if (e === 'NOT_ENOUGH_SPACE') {
// TODO update table to say not enough space?
return void common.alert(Messages.upload_notEnoughSpace);
}
console.error(e);
return void common.alert(Messages.upload_serverError);
};
var onPending = function (cb) {
common.confirm(Messages.upload_uploadPending, function (yes) {
if (!yes) { return; }
cb();
});
};
file.blob = u8;
module.upload(file, config.noStore, common, updateProgress, onComplete, onError, onPending);
};
var prettySize = function (bytes) {
var kB = common.bytesToKilobytes(bytes);
if (kB < 1024) { return kB + Messages.KB; }
var mB = common.bytesToMegabytes(bytes);
return mB + Messages.MB;
};
queue.next = function () {
if (queue.queue.length === 0) {
queue.to = window.setTimeout(function () {
if (config.keepTable) { return; }
File.$container.fadeOut();
}, 3000);
return;
}
if (queue.inProgress) { return; }
File.$container.show();
var file = queue.queue.shift();
upload(file);
};
queue.push = function (obj) {
var id = uid();
obj.id = id;
queue.queue.push(obj);
$table.show();
var estimate = FileCrypto.computeEncryptedSize(obj.blob.byteLength, obj.metadata);
var $progressBar = $('<div>', {'class':'progressContainer'});
var $progressValue = $('<span>', {'class':'progressValue'}).text(Messages.upload_pending);
var $tr = $('<tr>', {id: id}).appendTo($table);
var $cancel = $('<span>', {'class': 'cancel fa fa-times'}).click(function () {
queue.queue = queue.queue.filter(function (el) { return el.id !== id; });
$cancel.remove();
$tr.find('.upCancel').text('-');
$tr.find('.progressValue').text(Messages.upload_cancelled);
});
var $link = $('<a>', {
'class': 'upLink',
'rel': 'noopener noreferrer'
}).text(obj.metadata.name);
$('<td>').append($link).appendTo($tr);
$('<td>').text(prettySize(estimate)).appendTo($tr);
$('<td>', {'class': 'upProgress'}).append($progressBar).append($progressValue).appendTo($tr);
$('<td>', {'class': 'upCancel'}).append($cancel).appendTo($tr);
queue.next();
};
var handleFile = File.handleFile = function (file, e, thumbnail) {
var thumb;
var file_arraybuffer;
var finish = function () {
var metadata = {
name: file.name,
type: file.type,
};
if (thumb) { metadata.thumbnail = thumb; }
queue.push({
blob: file_arraybuffer,
metadata: metadata,
dropEvent: e
});
};
blobToArrayBuffer(file, function (e, buffer) {
if (e) { console.error(e); }
file_arraybuffer = buffer;
if (thumbnail) { // there is already a thumbnail
return blobToArrayBuffer(thumbnail, function (e, buffer) {
if (e) { console.error(e); }
thumb = arrayBufferToString(buffer);
finish();
});
}
if (!Thumb.isSupportedType(file.type)) { return finish(); }
// make a resized thumbnail from the image..
Thumb.fromBlob(file, function (e, thumb64) {
if (e) { console.error(e); }
if (!thumb64) { return finish(); }
thumb = thumb64;
finish();
});
});
};
var onFileDrop = File.onFileDrop = function (file, e) {
if (!common.isLoggedIn()) {
return common.alert(common.Messages.upload_mustLogin);
}
Array.prototype.slice.call(file).forEach(function (d) {
handleFile(d, e);
});
};
var createAreaHandlers = File.createDropArea = function ($area, $hoverArea) {
var counter = 0;
if (!$hoverArea) { $hoverArea = $area; }
if (!$area) { return; }
$hoverArea
.on('dragenter', function (e) {
e.preventDefault();
e.stopPropagation();
counter++;
$hoverArea.addClass('hovering');
})
.on('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
counter--;
if (counter <= 0) {
$hoverArea.removeClass('hovering');
}
});
$area
.on('drag dragstart dragend dragover drop dragenter dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
})
.on('drop', function (e) {
e.stopPropagation();
var dropped = e.originalEvent.dataTransfer.files;
counter = 0;
$hoverArea.removeClass('hovering');
onFileDrop(dropped, e);
});
};
var createUploader = function ($area, $hover, $body) {
if (!config.noHandlers) {
createAreaHandlers($area, null);
}
createTableContainer($body);
};
createUploader(config.dropArea, config.hoverArea, config.body);
return File;
};
return module;
});

@ -1,9 +1,8 @@
define([
'/common/common-util.js',
'/common/common-interface.js',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/tweetnacl/nacl-fast.min.js'
], function (Util, UI, Crypto) {
], function (Util, Crypto) {
var Nacl = window.nacl;
var Hash = {};
@ -211,14 +210,12 @@ Version 1
secret.keys = Crypto.createEditCryptor(parsed.key);
secret.key = secret.keys.editKeyStr;
if (secret.channel.length !== 32 || secret.key.length !== 24) {
UI.alert("The channel key and/or the encryption key is invalid");
throw new Error("The channel key and/or the encryption key is invalid");
}
}
else if (parsed.mode === 'view') {
secret.keys = Crypto.createViewCryptor(parsed.key);
if (secret.channel.length !== 32) {
UI.alert("The channel key is invalid");
throw new Error("The channel key is invalid");
}
}

@ -1,268 +0,0 @@
define([
'jquery',
'/bower_components/chainpad-json-validator/json-ot.js',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/chainpad/chainpad.dist.js',
], function ($, JsonOT, Crypto) {
var ChainPad = window.ChainPad;
var History = {};
var getStates = function (rt) {
var states = [];
var b = rt.getAuthBlock();
if (b) { states.unshift(b); }
while (b.getParent()) {
b = b.getParent();
states.unshift(b);
}
return states;
};
var loadHistory = function (config, common, cb) {
var network = common.getNetwork();
var hkn = network.historyKeeper;
var wcId = common.hrefToHexChannelId(config.href || window.location.href);
var createRealtime = function () {
return ChainPad.create({
userName: 'history',
initialState: '',
transformFunction: JsonOT.validate,
logLevel: 0,
noPrune: true
});
};
var realtime = createRealtime();
var parsed = config.href ? common.parsePadUrl(config.href) : {};
var secret = common.getSecrets(parsed.type, parsed.hash);
History.readOnly = 0;
if (!secret.keys) {
secret.keys = secret.key;
History.readOnly = 0;
}
else if (!secret.keys.validateKey) {
History.readOnly = 1;
}
var crypto = Crypto.createEncryptor(secret.keys);
var to = window.setTimeout(function () {
cb('[GET_FULL_HISTORY_TIMEOUT]');
}, 30000);
var parse = function (msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
var onMsg = function (msg) {
var parsed = parse(msg);
if (parsed[0] === 'FULL_HISTORY_END') {
console.log('END');
window.clearTimeout(to);
cb(null, realtime);
return;
}
if (parsed[0] !== 'FULL_HISTORY') { return; }
if (parsed[1] && parsed[1].validateKey) { // First message
secret.keys.validateKey = parsed[1].validateKey;
return;
}
msg = parsed[1][4];
if (msg) {
msg = msg.replace(/^cp\|/, '');
var decryptedMsg = crypto.decrypt(msg, secret.keys.validateKey);
realtime.message(decryptedMsg);
}
};
network.on('message', function (msg) {
onMsg(msg);
});
network.sendto(hkn, JSON.stringify(['GET_FULL_HISTORY', wcId, secret.keys.validateKey]));
};
History.create = function (common, config) {
if (!config.$toolbar) { return void console.error("config.$toolbar is undefined");}
if (History.loading) { return void console.error("History is already being loaded..."); }
History.loading = true;
var $toolbar = config.$toolbar;
if (!config.applyVal || !config.setHistory || !config.onLocal || !config.onRemote) {
throw new Error("Missing config element: applyVal, onLocal, onRemote, setHistory");
}
// config.setHistory(bool, bool)
// - bool1: history value
// - bool2: reset old content?
var render = function (val) {
if (typeof val === "undefined") { return; }
try {
config.applyVal(val);
} catch (e) {
// Probably a parse error
console.error(e);
}
};
var onClose = function () { config.setHistory(false, true); };
var onRevert = function () {
config.setHistory(false, false);
config.onLocal();
config.onRemote();
};
var onReady = function () {
config.setHistory(true);
};
var Messages = common.Messages;
var realtime;
var states = [];
var c = states.length - 1;
var $hist = $toolbar.find('.cryptpad-toolbar-history');
var $left = $toolbar.find('.cryptpad-toolbar-leftside');
var $right = $toolbar.find('.cryptpad-toolbar-rightside');
var $cke = $toolbar.find('.cke_toolbox_main');
$hist.html('').show();
$left.hide();
$right.hide();
$cke.hide();
common.spinner($hist).get().show();
var onUpdate;
var update = function () {
if (!realtime) { return []; }
states = getStates(realtime);
if (typeof onUpdate === "function") { onUpdate(); }
return states;
};
// Get the content of the selected version, and change the version number
var get = function (i) {
i = parseInt(i);
if (isNaN(i)) { return; }
if (i < 0) { i = 0; }
if (i > states.length - 1) { i = states.length - 1; }
var val = states[i].getContent().doc;
c = i;
if (typeof onUpdate === "function") { onUpdate(); }
$hist.find('.next, .previous').css('visibility', '');
if (c === states.length - 1) { $hist.find('.next').css('visibility', 'hidden'); }
if (c === 0) { $hist.find('.previous').css('visibility', 'hidden'); }
return val || '';
};
var getNext = function (step) {
return typeof step === "number" ? get(c + step) : get(c + 1);
};
var getPrevious = function (step) {
return typeof step === "number" ? get(c - step) : get(c - 1);
};
// Create the history toolbar
var display = function () {
$hist.html('');
var $prev =$('<button>', {
'class': 'previous fa fa-step-backward buttonPrimary',
title: Messages.history_prev
}).appendTo($hist);
var $nav = $('<div>', {'class': 'goto'}).appendTo($hist);
var $next = $('<button>', {
'class': 'next fa fa-step-forward buttonPrimary',
title: Messages.history_next
}).appendTo($hist);
$('<label>').text(Messages.history_version).appendTo($nav);
var $cur = $('<input>', {
'class' : 'gotoInput',
'type' : 'number',
'min' : '1',
'max' : states.length
}).val(c + 1).appendTo($nav).mousedown(function (e) {
// stopPropagation because the event would be cancelled by the dropdown menus
e.stopPropagation();
});
var $label2 = $('<label>').text(' / '+ states.length).appendTo($nav);
$('<br>').appendTo($nav);
var $close = $('<button>', {
'class':'closeHistory',
title: Messages.history_closeTitle
}).text(Messages.history_closeTitle).appendTo($nav);
var $rev = $('<button>', {
'class':'revertHistory buttonSuccess',
title: Messages.history_restoreTitle
}).text(Messages.history_restore).appendTo($nav);
if (History.readOnly) { $rev.hide(); }
onUpdate = function () {
$cur.attr('max', states.length);
$cur.val(c+1);
$label2.text(' / ' + states.length);
};
var close = function () {
$hist.hide();
$left.show();
$right.show();
$cke.show();
};
// Buttons actions
$prev.click(function () { render(getPrevious()); });
$next.click(function () { render(getNext()); });
$cur.keydown(function (e) {
var p = function () { e.preventDefault(); };
if (e.which === 13) { p(); return render( get($cur.val() - 1) ); } // Enter
if ([37, 40].indexOf(e.which) >= 0) { p(); return render(getPrevious()); } // Left
if ([38, 39].indexOf(e.which) >= 0) { p(); return render(getNext()); } // Right
if (e.which === 33) { p(); return render(getNext(10)); } // PageUp
if (e.which === 34) { p(); return render(getPrevious(10)); } // PageUp
if (e.which === 27) { p(); $close.click(); }
}).keyup(function (e) { e.stopPropagation(); }).focus();
$cur.on('change', function () {
render( get($cur.val() - 1) );
});
$close.click(function () {
states = [];
close();
onClose();
});
$rev.click(function () {
common.confirm(Messages.history_restorePrompt, function (yes) {
if (!yes) { return; }
close();
onRevert();
common.log(Messages.history_restoreDone);
});
});
// Display the latest content
render(get(c));
};
// Load all the history messages into a new chainpad object
loadHistory(config, common, function (err, newRt) {
History.loading = false;
if (err) { throw new Error(err); }
realtime = newRt;
update();
c = states.length - 1;
display();
onReady();
});
};
return History;
});

@ -1,87 +0,0 @@
define(['jquery'], function ($) {
var module = {};
module.create = function (cfg, onLocal, Cryptpad) {
var exp = {};
var parsed = exp.parsedHref = Cryptpad.parsePadUrl(window.location.href);
exp.defaultTitle = Cryptpad.getDefaultName(parsed);
exp.title = document.title; // TOOD slides
cfg = cfg || {};
var getHeadingText = cfg.getHeadingText || function () { return; };
var updateLocalTitle = function (newTitle) {
exp.title = newTitle;
onLocal();
if (typeof cfg.updateLocalTitle === "function") {
cfg.updateLocalTitle(newTitle);
} else {
document.title = newTitle;
}
};
var $title;
exp.setToolbar = function (toolbar) {
$title = toolbar && toolbar.title;
};
exp.getTitle = function () { return exp.title; };
var isDefaultTitle = exp.isDefaultTitle = function (){return exp.title === exp.defaultTitle;};
var suggestTitle = exp.suggestTitle = function (fallback) {
if (isDefaultTitle()) {
return getHeadingText() || fallback || "";
} else {
return exp.title || getHeadingText() || exp.defaultTitle;
}
};
var renameCb = function (err, newTitle) {
if (err) { return; }
updateLocalTitle(newTitle);
onLocal();
};
// update title: href is optional; if not specified, we use window.location.href
exp.updateTitle = function (newTitle, href, cb) {
cb = cb || $.noop;
if (newTitle === exp.title) { return; }
// Change the title now, and set it back to the old value if there is an error
var oldTitle = exp.title;
Cryptpad.renamePad(newTitle, href, function (err, data) {
if (err) {
console.log("Couldn't set pad title");
console.error(err);
updateLocalTitle(oldTitle);
return void cb(err);
}
updateLocalTitle(data);
cb(null, data);
if (!$title) { return; }
$title.find('span.title').text(data);
$title.find('input').val(data);
});
};
exp.updateDefaultTitle = function (newDefaultTitle) {
exp.defaultTitle = newDefaultTitle;
if (!$title) { return; }
$title.find('input').attr("placeholder", exp.defaultTitle);
};
exp.getTitleConfig = function () {
return {
onRename: renameCb,
suggestName: suggestTitle,
defaultName: exp.defaultTitle
};
};
return exp;
};
return module;
});

@ -1,117 +0,0 @@
define(['json.sortify'], function (Sortify) {
var module = {};
module.create = function (info, onLocal, Cryptget, Cryptpad) {
var exp = {};
var userData = exp.userData = {};
var userList = exp.userList = info.userList;
var myData = exp.myData = {};
exp.myUserName = info.myID;
exp.myNetfluxId = info.myID;
var network = Cryptpad.getNetwork();
var parsed = Cryptpad.parsePadUrl(window.location.href);
var appType = parsed ? parsed.type : undefined;
var oldUserData = {};
var addToUserData = exp.addToUserData = function(data) {
var users = userList.users;
for (var attrname in data) { userData[attrname] = data[attrname]; }
if (users && users.length) {
for (var userKey in userData) {
if (users.indexOf(userKey) === -1) {
delete userData[userKey];
}
}
}
if(userList && typeof userList.onChange === "function") {
// Make sure we don't update the userlist everytime someone makes a change to the pad
if (Sortify(oldUserData) === Sortify(userData)) { return; }
oldUserData = JSON.parse(JSON.stringify(userData));
userList.onChange(userData);
}
};
exp.getToolbarConfig = function () {
return {
data: userData,
list: userList,
userNetfluxId: exp.myNetfluxId
};
};
var setName = exp.setName = function (newName, cb) {
if (typeof(newName) !== 'string') { return; }
var myUserNameTemp = newName.trim();
if(myUserNameTemp.length > 32) {
myUserNameTemp = myUserNameTemp.substr(0, 32);
}
exp.myUserName = myUserNameTemp;
myData = {};
myData[exp.myNetfluxId] = {
name: exp.myUserName,
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: Cryptpad.getProxy().curvePublic
};
addToUserData(myData);
/*Cryptpad.setAttribute('username', exp.myUserName, function (err) {
if (err) {
console.log("Couldn't set username");
console.error(err);
return;
}
if (typeof cb === "function") { cb(); }
});*/
if (typeof cb === "function") { cb(); }
};
exp.getLastName = function ($changeNameButton, isNew) {
Cryptpad.getLastName(function (err, lastName) {
if (err) {
console.log("Could not get previous name");
console.error(err);
return;
}
// Update the toolbar list:
// Add the current user in the metadata
if (typeof(lastName) === 'string') {
setName(lastName, onLocal);
} else {
myData[exp.myNetfluxId] = {
name: "",
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: Cryptpad.getProxy().curvePublic
};
addToUserData(myData);
onLocal();
$changeNameButton.click();
}
if (isNew && appType) {
Cryptpad.selectTemplate(appType, info.realtime, Cryptget);
}
});
};
Cryptpad.onDisplayNameChanged(function (newName) {
setName(newName, onLocal);
});
network.on('reconnect', function (uid) {
exp.myNetfluxId = uid;
exp.setName(exp.myUserName);
});
return exp;
};
return module;
});

@ -1,112 +0,0 @@
define(function () {
var module = {};
module.create = function (info, onLocal, Cryptget, Cryptpad) {
var exp = {};
var userData = exp.userData = {};
var userList = exp.userList = info.userList;
var myData = exp.myData = {};
exp.myUserName = info.myID;
exp.myNetfluxId = info.myID;
var network = Cryptpad.getNetwork();
var parsed = Cryptpad.parsePadUrl(window.location.href);
var appType = parsed ? parsed.type : undefined;
var addToUserData = exp.addToUserData = function(data) {
var users = userList.users;
for (var attrname in data) { userData[attrname] = data[attrname]; }
if (users && users.length) {
for (var userKey in userData) {
if (users.indexOf(userKey) === -1) {
delete userData[userKey];
}
}
}
if(userList && typeof userList.onChange === "function") {
userList.onChange(userData);
}
};
exp.getToolbarConfig = function () {
return {
data: userData,
list: userList,
userNetfluxId: exp.myNetfluxId
};
};
var setName = exp.setName = function (newName, cb) {
if (typeof(newName) !== 'string') { return; }
var myUserNameTemp = newName.trim();
if(myUserNameTemp.length > 32) {
myUserNameTemp = myUserNameTemp.substr(0, 32);
}
exp.myUserName = myUserNameTemp;
myData = {};
myData[exp.myNetfluxId] = {
name: exp.myUserName,
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: Cryptpad.getProxy().curvePublic
};
addToUserData(myData);
/*Cryptpad.setAttribute('username', exp.myUserName, function (err) {
if (err) {
console.log("Couldn't set username");
console.error(err);
return;
}
if (typeof cb === "function") { cb(); }
});*/
if (typeof cb === "function") { cb(); }
};
exp.getLastName = function ($changeNameButton, isNew) {
Cryptpad.getLastName(function (err, lastName) {
if (err) {
console.log("Could not get previous name");
console.error(err);
return;
}
// Update the toolbar list:
// Add the current user in the metadata
if (typeof(lastName) === 'string') {
setName(lastName, onLocal);
} else {
myData[exp.myNetfluxId] = {
name: "",
uid: Cryptpad.getUid(),
avatar: Cryptpad.getAvatarUrl(),
profile: Cryptpad.getProfileUrl(),
curvePublic: Cryptpad.getProxy().curvePublic
};
addToUserData(myData);
onLocal();
$changeNameButton.click();
}
if (isNew && appType) {
Cryptpad.selectTemplate(appType, info.realtime, Cryptget);
}
});
};
Cryptpad.onDisplayNameChanged(function (newName) {
setName(newName, onLocal);
});
network.on('reconnect', function (uid) {
exp.myNetfluxId = uid;
exp.setName(exp.myUserName);
});
return exp;
};
return module;
});

@ -6,13 +6,7 @@ define([
'/common/common-util.js',
'/common/common-hash.js',
'/common/common-interface.js',
'/common/common-history.js',
'/common/common-userlist.js',
'/common/common-title.js',
'/common/common-metadata.js',
'/common/common-messaging.js',
'/common/common-codemirror.js',
'/common/common-file.js',
'/file/file-crypto.js',
'/common/common-realtime.js',
'/common/common-language.js',
@ -23,8 +17,8 @@ define([
'/common/media-tag.js',
'/bower_components/nthen/index.js',
'/bower_components/localforage/dist/localforage.min.js',
], function ($, Config, Messages, Store, Util, Hash, UI, History, UserList, Title, Metadata,
Messaging, CodeMirror, Files, FileCrypto, Realtime, Language, Clipboard,
], function ($, Config, Messages, Store, Util, Hash, UI,
Messaging, FileCrypto, Realtime, Language, Clipboard,
Pinpad, AppConfig, MediaTag, Nthen, localForage) {
// Configure MediaTags to use our local viewer
@ -111,7 +105,7 @@ define([
var createRandomHash = common.createRandomHash = Hash.createRandomHash;
common.parseTypeHash = Hash.parseTypeHash;
var parsePadUrl = common.parsePadUrl = Hash.parsePadUrl;
var isNotStrongestStored = common.isNotStrongestStored = Hash.isNotStrongestStored;
common.isNotStrongestStored = Hash.isNotStrongestStored;
var hrefToHexChannelId = common.hrefToHexChannelId = Hash.hrefToHexChannelId;
var getRelativeHref = common.getRelativeHref = Hash.getRelativeHref;
common.getBlobPathFromHex = Hash.getBlobPathFromHex;
@ -146,24 +140,6 @@ define([
Realtime.beginDetectingInfiniteSpinner(common, realtime);
};
// Userlist
common.createUserList = UserList.create;
// Title
common.createTitle = Title.create;
// Metadata
common.createMetadata = Metadata.create;
// CodeMirror
common.createCodemirror = CodeMirror.create;
// Files
common.createFileManager = function (config) { return Files.create(common, config); };
// History
common.getHistory = function (config) { return History.create(common, config); };
var getStore = common.getStore = function () {
if (store) { return store; }
throw new Error("Store is not ready!");
@ -1131,9 +1107,6 @@ define([
rpc.uploadCancel(cb);
};
common.uploadFileSecure = Files.upload;
/* 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
@ -1228,17 +1201,9 @@ define([
cb(null, $container);
};
var prepareFeedback = common.prepareFeedback = function (key) {
if (typeof(key) !== 'string') { return $.noop; }
var type = common.getAppType();
return function () {
feedback((key + (type? '_' + type: '')).toUpperCase());
};
};
// Forget button
var moveToTrash = common.moveToTrash = function (cb, href) {
// TODO REFACTOR only used in sframe-common-outer
common.moveToTrash = function (cb, href) {
href = href || window.location.href;
common.forgetPad(href, function (err) {
if (err) {
@ -1259,7 +1224,8 @@ define([
}
});
};
var saveAsTemplate = common.saveAsTemplate = function (Cryptput, data, cb) {
// TODO REFACTOR only used in sframe-common-outer
common.saveAsTemplate = function (Cryptput, data, cb) {
var p = parsePadUrl(window.location.href);
if (!p.type) { return; }
var hash = createRandomHash();
@ -1272,209 +1238,6 @@ define([
});
});
};
common.createButton = function (type, rightside, data, callback) {
var button;
var size = "17px";
switch (type) {
case 'export':
button = $('<button>', {
'class': 'fa fa-download',
title: Messages.exportButtonTitle,
}).append($('<span>', {'class': 'drawer'}).text(Messages.exportButton));
button.click(prepareFeedback(type));
if (callback) {
button.click(callback);
}
break;
case 'import':
button = $('<button>', {
'class': 'fa fa-upload',
title: Messages.importButtonTitle,
}).append($('<span>', {'class': 'drawer'}).text(Messages.importButton));
if (callback) {
button
.click(prepareFeedback(type))
.click(UI.importContent('text/plain', function (content, file) {
callback(content, file);
}, {accept: data ? data.accept : undefined}));
}
break;
case 'upload':
console.log('UPLOAD');
button = $('<button>', {
'class': 'btn btn-primary new',
title: Messages.uploadButtonTitle,
}).append($('<span>', {'class':'fa fa-upload'})).append(' '+Messages.uploadButton);
if (!data.FM) { return; }
var $input = $('<input>', {
'type': 'file',
'style': 'display: none;'
}).on('change', function (e) {
var file = e.target.files[0];
var ev = {
target: data.target
};
if (data.filter && !data.filter(file)) {
common.log('TODO: invalid avatar (type or size)');
return;
}
data.FM.handleFile(file, ev);
if (callback) { callback(); }
});
if (data.accept) { $input.attr('accept', data.accept); }
button.click(function () { $input.click(); });
break;
case 'template':
if (!AppConfig.enableTemplates) { return; }
button = $('<button>', {
title: Messages.saveTemplateButton,
}).append($('<span>', {'class':'fa fa-bookmark', style: 'font:'+size+' FontAwesome'}));
if (data.rt && data.Crypt) {
button
.click(function () {
var title = data.getTitle() || document.title;
var todo = function (val) {
if (typeof(val) !== "string") { return; }
var toSave = data.rt.getUserDoc();
if (val.trim()) {
val = val.trim();
title = val;
try {
var parsed = JSON.parse(toSave);
var meta;
if (Array.isArray(parsed) && typeof(parsed[3]) === "object") {
meta = parsed[3].metadata; // pad
} else if (parsed.info) {
meta = parsed.info; // poll
} else {
meta = parsed.metadata;
}
if (typeof(meta) === "object") {
meta.title = val;
meta.defaultTitle = val;
delete meta.users;
}
toSave = JSON.stringify(parsed);
} catch(e) {
console.error("Parse error while setting the title", e);
}
}
saveAsTemplate(data.Crypt.put, {
title: title,
toSave: toSave
}, function () {
common.alert(Messages.templateSaved);
common.feedback('TEMPLATE_CREATED');
});
};
common.prompt(Messages.saveTemplatePrompt, title || document.title, todo);
});
}
break;
case 'forget':
button = $('<button>', {
id: 'cryptpad-forget',
title: Messages.forgetButtonTitle,
'class': "fa fa-trash cryptpad-forget",
style: 'font:'+size+' FontAwesome'
});
getRecentPads(function (err, recent) {
if (isNotStrongestStored(window.location.href, recent)) {
button.addClass('hidden');
}
});
if (callback) {
button
.click(prepareFeedback(type))
.click(function() {
var msg = isLoggedIn() ? Messages.forgetPrompt : Messages.fm_removePermanentlyDialog;
common.confirm(msg, function (yes) {
if (!yes) { return; }
moveToTrash(function (err) {
if (err) { return void callback(err); }
var cMsg = isLoggedIn() ? Messages.movedToTrash : Messages.deleted;
common.alert(cMsg, undefined, true);
callback();
return;
});
});
});
}
break;
case 'present':
button = $('<button>', {
title: Messages.presentButtonTitle,
'class': "fa fa-play-circle cryptpad-present-button", // class used in slide.js
style: 'font:'+size+' FontAwesome'
});
break;
case 'source':
button = $('<button>', {
title: Messages.sourceButtonTitle,
'class': "fa fa-stop-circle cryptpad-source-button", // class used in slide.js
style: 'font:'+size+' FontAwesome'
});
break;
case 'history':
if (!AppConfig.enableHistory) {
button = $('<span>');
break;
}
button = $('<button>', {
title: Messages.historyButton,
'class': "fa fa-history history",
}).append($('<span>', {'class': 'drawer'}).text(Messages.historyText));
if (data.histConfig) {
button
.click(prepareFeedback(type))
.on('click', function () {
common.getHistory(data.histConfig);
});
}
break;
case 'more':
button = $('<button>', {
title: Messages.moreActions || 'TODO',
'class': "drawer-button fa fa-ellipsis-h",
style: 'font:'+size+' FontAwesome'
});
break;
case 'savetodrive':
button = $('<button>', {
'class': 'fa fa-cloud-upload',
title: Messages.canvas_saveToDrive,
})
.click(prepareFeedback(type));
break;
case 'hashtag':
button = $('<button>', {
'class': 'fa fa-hashtag',
})
.click(prepareFeedback(type))
.click(function () {
// TODO fetch pad tags before presenting dialog to user
var dialog = UI.dialog.tagPrompt([], function (tags) {
if (!Array.isArray(tags)) { return; }
console.error(tags);
// TODO do something with the tags the user entered
});
document.body.appendChild(dialog);
});
break;
default:
button = $('<button>', {
'class': "fa fa-question",
style: 'font:'+size+' FontAwesome'
})
.click(prepareFeedback(type));
}
if (rightside) {
button.addClass('rightside-button');
}
return button;
};
var emoji_patt = /([\uD800-\uDBFF][\uDC00-\uDFFF])/;
var isEmoji = function (str) {
@ -1564,73 +1327,6 @@ define([
'image/jpg',
'image/gif',
];
// SFRAME: copied to sframe-common-interface.js
common.displayAvatar = function ($container, href, name, cb) {
var MutationObserver = window.MutationObserver;
var displayDefault = function () {
var text = getFirstEmojiOrCharacter(name);
var $avatar = $('<span>', {'class': 'default'}).text(text);
$container.append($avatar);
if (cb) { cb(); }
};
if (!href) { return void displayDefault(); }
var parsed = common.parsePadUrl(href);
var secret = common.getSecrets('file', parsed.hash);
if (secret.keys && secret.channel) {
var cryptKey = secret.keys && secret.keys.fileKeyStr;
var hexFileName = common.base64ToHex(secret.channel);
var src = common.getBlobPathFromHex(hexFileName);
common.getFileSize(href, function (e, data) {
if (e) {
displayDefault();
return void console.error(e);
}
if (typeof data !== "number") { return void displayDefault(); }
if (common.bytesToMegabytes(data) > 0.5) { return void displayDefault(); }
var $img = $('<media-tag>').appendTo($container);
$img.attr('src', src);
$img.attr('data-crypto-key', 'cryptpad:' + cryptKey);
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' && mutation.addedNodes.length) {
if (mutation.addedNodes.length > 1 ||
mutation.addedNodes[0].nodeName !== 'IMG') {
$img.remove();
return void displayDefault();
}
var $image = $img.find('img');
var onLoad = function () {
var img = new Image();
img.onload = function () {
var w = img.width;
var h = img.height;
if (w>h) {
$image.css('max-height', '100%');
$img.css('flex-direction', 'column');
if (cb) { cb($img); }
return;
}
$image.css('max-width', '100%');
$img.css('flex-direction', 'row');
if (cb) { cb($img); }
};
img.src = $image.attr('src');
};
if ($image[0].complete) { onLoad(); }
$image.on('load', onLoad);
}
});
});
observer.observe($img[0], {
attributes: false,
childList: true,
characterData: false
});
MediaTag($img[0]);
});
}
};
// This is duplicated in drive/main.js, it should be unified
var getFileIcon = common.getFileIcon = function (data) {
@ -1882,195 +1578,6 @@ define([
return $container;
};
// Provide $container if you want to put the generated block in another element
// Provide $initBlock if you already have the menu block and you want the content inserted in it
common.createLanguageSelector = function ($container, $initBlock) {
var options = [];
var languages = Messages._languages;
var keys = Object.keys(languages).sort();
keys.forEach(function (l) {
options.push({
tag: 'a',
attributes: {
'class': 'languageValue',
'data-value': l,
'href': '#',
},
content: languages[l] // Pretty name of the language value
});
});
var dropdownConfig = {
text: Messages.language, // Button initial text
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
container: $initBlock, // optional
isSelect: true
};
var $block = createDropdown(dropdownConfig);
$block.attr('id', 'language-selector');
if ($container) {
$block.appendTo($container);
}
Language.initSelector($block);
return $block;
};
// SFRAME: moved to sframe-common-interface.js
common.createUserAdminMenu = function (config) {
var $displayedName = $('<span>', {'class': config.displayNameCls || 'displayName'});
var accountName = localStorage[common.userNameKey];
var account = isLoggedIn();
var $userName = $('<span>', {'class': 'userDisplayName'});
var options = [];
if (config.displayNameCls) {
var $userAdminContent = $('<p>');
if (account) {
var $userAccount = $('<span>', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + fixHTML(accountName));
$userAdminContent.append($userAccount);
$userAdminContent.append($('<br>'));
}
if (config.displayName) {
// Hide "Display name:" in read only mode
$userName.append(Messages.user_displayName + ': ');
$userName.append($displayedName.clone());
}
$userAdminContent.append($userName);
options.push({
tag: 'p',
attributes: {'class': 'accountData'},
content: $userAdminContent.html()
});
}
var parsed = parsePadUrl(window.location.href);
if (parsed && (!parsed.type || parsed.type && parsed.type !== 'drive')) {
options.push({
tag: 'a',
attributes: {
'target': '_blank',
'href': '/drive/'
},
content: Messages.login_accessDrive
});
}
// Add the change display name button if not in read only mode
if (config.changeNameButtonCls && config.displayChangeName) {
options.push({
tag: 'a',
attributes: {'class': config.changeNameButtonCls},
content: Messages.user_rename
});
}
if (account) {
options.push({
tag: 'a',
attributes: {'class': 'profile'},
content: Messages.profileButton
});
}
if (parsed && (!parsed.type || parsed.type !== 'settings')) {
options.push({
tag: 'a',
attributes: {'class': 'settings'},
content: Messages.settingsButton
});
}
// Add login or logout button depending on the current status
if (account) {
options.push({
tag: 'a',
attributes: {'class': 'logout'},
content: Messages.logoutButton
});
} else {
options.push({
tag: 'a',
attributes: {'class': 'login'},
content: Messages.login_login
});
options.push({
tag: 'a',
attributes: {'class': 'register'},
content: Messages.login_register
});
}
var $icon = $('<span>', {'class': 'fa fa-user-secret'});
//var $userbig = $('<span>', {'class': 'big'}).append($displayedName.clone());
var $userButton = $('<div>').append($icon);//.append($userbig);
if (account) {
$userButton = $('<div>').append(accountName);
}
/*if (account && config.displayNameCls) {
$userbig.append($('<span>', {'class': 'account-name'}).text('(' + accountName + ')'));
} else if (account) {
// If no display name, do not display the parentheses
$userbig.append($('<span>', {'class': 'account-name'}).text(accountName));
}*/
var dropdownConfigUser = {
text: $userButton.html(), // Button initial text
options: options, // Entries displayed in the menu
left: true, // Open to the left of the button
container: config.$initBlock, // optional
feedback: "USER_ADMIN",
};
var $userAdmin = createDropdown(dropdownConfigUser);
var oldUrl = '';
if (account && !config.static && store) {
var $avatar = $userAdmin.find('.cp-dropdown-button-title');
var updateButton = function (newName) {
var profile = store.getProfile();
var url = profile && profile.avatar;
if (oldUrl === url) { return; }
oldUrl = url;
$avatar.html('');
common.displayAvatar($avatar, url, newName || Messages.anonymous, function ($img) {
if ($img) {
$userAdmin.find('button').addClass('avatar');
}
});
};
common.onDisplayNameChanged(updateButton);
updateButton(common.getDisplayName());
}
$userAdmin.find('a.logout').click(function () {
common.logout();
window.location.href = '/';
});
$userAdmin.find('a.settings').click(function () {
if (parsed && parsed.type) {
window.open('/settings/');
} else {
window.location.href = '/settings/';
}
});
$userAdmin.find('a.profile').click(function () {
if (parsed && parsed.type) {
window.open('/profile/');
} else {
window.location.href = '/profile/';
}
});
$userAdmin.find('a.login').click(function () {
if (window.location.pathname !== "/") {
sessionStorage.redirectTo = window.location.href;
}
window.location.href = '/login/';
});
$userAdmin.find('a.register').click(function () {
if (window.location.pathname !== "/") {
sessionStorage.redirectTo = window.location.href;
}
window.location.href = '/register/';
});
return $userAdmin;
};
common.getShareHashes = function (secret, cb) {
if (!window.location.hash) {
var hashes = common.getHashes(secret.channel, secret);

@ -0,0 +1,92 @@
define([
'/file/file-crypto.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function (FileCrypto) {
var Nacl = window.nacl;
var module = {};
module.upload = function (file, noStore, common, updateProgress, onComplete, onError, onPending) {
var u8 = file.blob; // This is not a blob but a uint8array
var metadata = file.metadata;
// if it exists, path contains the new pad location in the drive
var path = file.path;
var key = Nacl.randomBytes(32);
var next = FileCrypto.encrypt(u8, metadata, key);
var estimate = FileCrypto.computeEncryptedSize(u8.length, metadata);
var sendChunk = function (box, cb) {
var enc = Nacl.util.encodeBase64(box);
common.rpc.send.unauthenticated('UPLOAD', enc, function (e, msg) {
cb(e, msg);
});
};
var actual = 0;
var again = function (err, box) {
if (err) { throw new Error(err); }
if (box) {
actual += box.length;
var progressValue = (actual / estimate * 100);
updateProgress(progressValue);
return void sendChunk(box, function (e) {
if (e) { return console.error(e); }
next(again);
});
}
if (actual !== estimate) {
console.error('Estimated size does not match actual size');
}
// if not box then done
common.uploadComplete(function (e, id) {
if (e) { return void console.error(e); }
var uri = ['', 'blob', id.slice(0,2), id].join('/');
console.log("encrypted blob is now available as %s", uri);
var b64Key = Nacl.util.encodeBase64(key);
var hash = common.getFileHashFromKeys(id, b64Key);
var href = '/file/#' + hash;
var title = metadata.name;
if (noStore) { return void onComplete(href); }
common.initialPath = path;
common.renamePad(title || "", href, function (err) {
if (err) { return void console.error(err); }
onComplete(href);
common.setPadAttribute('fileType', metadata.type, null, href);
});
});
};
common.uploadStatus(estimate, function (e, pending) {
if (e) {
console.error(e);
onError(e);
return;
}
if (pending) {
return void onPending(function () {
// if the user wants to cancel the pending upload to execute that one
common.uploadCancel(function (e, res) {
if (e) {
return void console.error(e);
}
console.log(res);
next(again);
});
});
}
next(again);
});
};
return module;
});

@ -346,6 +346,7 @@ define([
// File upload
var onFileUpload = function (sframeChan, data, cb) {
require(['/common/outer/upload.js'], function (Files) {
var sendEvent = function (data) {
sframeChan.event("EV_FILE_UPLOAD_STATE", data);
};
@ -373,8 +374,9 @@ define([
});
};
data.blob = Crypto.Nacl.util.decodeBase64(data.blob);
Cryptpad.uploadFileSecure(data, data.noStore, Cryptpad, updateProgress, onComplete, onError, onPending);
Files.upload(data, data.noStore, Cryptpad, updateProgress, onComplete, onError, onPending);
cb();
});
};
sframeChan.on('Q_UPLOAD_FILE', function (data, cb) {
onFileUpload(sframeChan, data, cb);

@ -5,7 +5,7 @@ define([
'/common/sframe-chainpad-netflux-inner.js',
'/common/sframe-channel.js',
'/common/sframe-common-title.js',
'/common/sframe-common-interface.js',
'/common/common-ui-elements.js',
'/common/sframe-common-history.js',
'/common/sframe-common-file.js',
'/common/sframe-common-codemirror.js',

File diff suppressed because it is too large Load Diff

@ -72,23 +72,6 @@ define([
$(function () {
var $main = $('#mainBlock');
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
// User admin menu
var $userMenu = $('#user-menu');
var userMenuCfg = {
$initBlock: $userMenu
};
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.find('button').addClass('btn').addClass('btn-secondary');
$(window).click(function () {
$('.cp-dropdown-content').hide();
});
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');

@ -9,24 +9,6 @@ define([
var $main = $('#mainBlock');
var Messages = Cryptpad.Messages;
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
// User admin menu
var $userMenu = $('#user-menu');
var userMenuCfg = {
$initBlock: $userMenu
};
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.find('button').addClass('btn').addClass('btn-secondary');
$(window).click(function () {
$('.cp-dropdown-content').hide();
});
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');

@ -14,7 +14,7 @@ define([
'/poll/render.js',
'/common/diffMarked.js',
'/common/sframe-common-codemirror.js',
'/common/sframe-common-interface.js',
'/common/common-ui-elements.js',
'/common/common-thumbnail.js',
'cm/lib/codemirror',

@ -12,24 +12,6 @@ define([
$(function () {
var $main = $('#mainBlock');
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
// User admin menu
var $userMenu = $('#user-menu');
var userMenuCfg = {
$initBlock: $userMenu
};
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.find('button').addClass('btn').addClass('btn-secondary');
$(window).click(function () {
$('.cp-dropdown-content').hide();
});
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');

@ -26,23 +26,6 @@ define([
$(function () {
var $main = $('#mainBlock');
// Language selector
var $sel = $('#language-selector');
Cryptpad.createLanguageSelector(undefined, $sel);
$sel.find('button').addClass('btn').addClass('btn-secondary');
$sel.show();
// User admin menu
var $userMenu = $('#user-menu');
var userMenuCfg = {
$initBlock: $userMenu
};
var $userAdmin = Cryptpad.createUserAdminMenu(userMenuCfg);
$userAdmin.find('button').addClass('btn').addClass('btn-secondary');
$(window).click(function () {
$('.cp-dropdown-content').hide();
});
// main block is hidden in case javascript is disabled
$main.removeClass('hidden');

@ -10,7 +10,7 @@ define([
'/common/cryptget.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/sframe-common-interface.js',
'/common/common-ui-elements.js',
'/api/config',
'/common/common-realtime.js',
'/customize/pages.js',

Loading…
Cancel
Save