Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging
This commit is contained in:
commit
ff151869de
61
customize.dist/delta-words.js
Normal file
61
customize.dist/delta-words.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
define([
|
||||||
|
'/bower_components/chainpad/chainpad.dist.js',
|
||||||
|
], function (ChainPad) {
|
||||||
|
var Diff = ChainPad.Diff;
|
||||||
|
|
||||||
|
var isSpace = function (S, i) {
|
||||||
|
return /^\s$/.test(S.charAt(i));
|
||||||
|
};
|
||||||
|
|
||||||
|
var leadingBoundary = function (S, offset) {
|
||||||
|
if (/\s/.test(S.charAt(offset))) { return offset; }
|
||||||
|
while (offset > 0) {
|
||||||
|
offset--;
|
||||||
|
if (isSpace(S, offset)) { offset++; break; }
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
var trailingBoundary = function (S, offset) {
|
||||||
|
if (isSpace(S, offset)) { return offset; }
|
||||||
|
while (offset < S.length && !/\s/.test(S.charAt(offset))) {
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
var opsToWords = function (previous, current) {
|
||||||
|
var output = [];
|
||||||
|
Diff.diff(previous, current).forEach(function (op) {
|
||||||
|
// ignore deleted sections...
|
||||||
|
var offset = op.offset;
|
||||||
|
var toInsert = op.toInsert;
|
||||||
|
|
||||||
|
// given an operation, check whether it is a word fragment,
|
||||||
|
// if it is, expand it to its word boundaries
|
||||||
|
var first = current.slice(leadingBoundary(current, offset), offset);
|
||||||
|
var last = current.slice(offset + toInsert.length, trailingBoundary(current, offset + toInsert.length));
|
||||||
|
|
||||||
|
var result = first + toInsert + last;
|
||||||
|
// concat-in-place
|
||||||
|
Array.prototype.push.apply(output, result.split(/\s+/));
|
||||||
|
});
|
||||||
|
return output.filter(Boolean);
|
||||||
|
};
|
||||||
|
|
||||||
|
var runningDiff = function (getter, f, time) {
|
||||||
|
var last = getter();
|
||||||
|
// first time through, send all the words :D
|
||||||
|
f(opsToWords("", last));
|
||||||
|
return setInterval(function () {
|
||||||
|
var current = getter();
|
||||||
|
|
||||||
|
// find inserted words...
|
||||||
|
var words = opsToWords(last, current);
|
||||||
|
last = current;
|
||||||
|
f(words);
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
|
||||||
|
return runningDiff;
|
||||||
|
});
|
||||||
0
customize.dist/translations/messages.el.js
Executable file → Normal file
0
customize.dist/translations/messages.el.js
Executable file → Normal file
@ -865,16 +865,16 @@ define(function () {
|
|||||||
out.creation_ownedTitle = "Type of pad";
|
out.creation_ownedTitle = "Type of pad";
|
||||||
out.creation_ownedTrue = "Owned pad";
|
out.creation_ownedTrue = "Owned pad";
|
||||||
out.creation_ownedFalse = "Open pad";
|
out.creation_ownedFalse = "Open pad";
|
||||||
out.creation_owned1 = "An <b>owned</b> pad is a pad that you can delete from the server whenever you want. Once it is deleted, no one else can access it, even if it is stored in their CryptDrive.";
|
out.creation_owned1 = "An <b>owned</b> pad can be deleted from the server whenever the owner wants. Deleting an owned pad removes it from other users' CryptDrives.";
|
||||||
out.creation_owned2 = "An <b>open</b> pad doesn't have any owner and thus, it can't be deleted from the server unless it has reached its expiration time.";
|
out.creation_owned2 = "An <b>open</b> pad doesn't have any owner and thus, it can't be deleted from the server unless it has reached its expiration time.";
|
||||||
out.creation_expireTitle = "Life time";
|
out.creation_expireTitle = "Life time";
|
||||||
out.creation_expireTrue = "Add a life time";
|
out.creation_expireTrue = "Add a life time";
|
||||||
out.creation_expireFalse = "Unlimited";
|
out.creation_expireFalse = "Unlimited";
|
||||||
out.creation_expireHours = "Hours";
|
out.creation_expireHours = "Hour(s)";
|
||||||
out.creation_expireDays = "Days";
|
out.creation_expireDays = "Day(s)";
|
||||||
out.creation_expireMonths = "Months";
|
out.creation_expireMonths = "Month(s)";
|
||||||
out.creation_expire1 = "By default, a pad stored by a registered user will never be removed from the server, unless it is requested by its owner.";
|
out.creation_expire1 = "An <b>unlimited</b> pad will not be removed from the server until its owner deletes it.";
|
||||||
out.creation_expire2 = "If you prefer, you can set a life time to make sure the pad will be permanently deleted from the server and unavailable after the specified date.";
|
out.creation_expire2 = "An <b>expiring</b> pad has a set lifetime, after which it will be automatically removed from the server and other users' CryptDrives.";
|
||||||
out.creation_createTitle = "Create a pad";
|
out.creation_createTitle = "Create a pad";
|
||||||
out.creation_createFromTemplate = "From template";
|
out.creation_createFromTemplate = "From template";
|
||||||
out.creation_createFromScratch = "From scratch";
|
out.creation_createFromScratch = "From scratch";
|
||||||
|
|||||||
93
expire-channels.js
Normal file
93
expire-channels.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
var Fs = require("fs");
|
||||||
|
var Path = require("path");
|
||||||
|
|
||||||
|
var nThen = require("nthen");
|
||||||
|
var config = require("./config");
|
||||||
|
|
||||||
|
var root = Path.resolve(config.taskPath || './tasks');
|
||||||
|
|
||||||
|
var dirs;
|
||||||
|
var nt;
|
||||||
|
|
||||||
|
var queue = function (f) {
|
||||||
|
nt = nt.nThen(f);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tryParse = function (s) {
|
||||||
|
try { return JSON.parse(s); }
|
||||||
|
catch (e) { return null; }
|
||||||
|
};
|
||||||
|
|
||||||
|
var CURRENT = +new Date();
|
||||||
|
|
||||||
|
var handleTask = function (str, path, cb) {
|
||||||
|
var task = tryParse(str);
|
||||||
|
if (!Array.isArray(task)) {
|
||||||
|
console.error('invalid task: not array');
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
if (task.length < 2) {
|
||||||
|
console.error('invalid task: too small');
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
var time = task[0];
|
||||||
|
var command = task[1];
|
||||||
|
var args = task.slice(2);
|
||||||
|
|
||||||
|
if (time > CURRENT) {
|
||||||
|
// not time for this task yet
|
||||||
|
console.log('not yet time');
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
nThen(function () {
|
||||||
|
switch (command) {
|
||||||
|
case 'EXPIRE':
|
||||||
|
console.log("expiring: %s", args[0]);
|
||||||
|
// TODO actually remove the file...
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log("unknown command", command);
|
||||||
|
}
|
||||||
|
}).nThen(function () {
|
||||||
|
// remove the file...
|
||||||
|
Fs.unlink(path, function (err) {
|
||||||
|
if (err) { console.error(err); }
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
nt = nThen(function (w) {
|
||||||
|
Fs.readdir(root, w(function (e, list) {
|
||||||
|
if (e) { throw e; }
|
||||||
|
dirs = list;
|
||||||
|
}));
|
||||||
|
}).nThen(function () {
|
||||||
|
dirs.forEach(function (dir) {
|
||||||
|
queue(function (w) {
|
||||||
|
console.log('recursing into %s', dir);
|
||||||
|
Fs.readdir(Path.join(root, dir), w(function (e, list) {
|
||||||
|
list.forEach(function (fn) {
|
||||||
|
queue(function (w) {
|
||||||
|
var filePath = Path.join(root, dir, fn);
|
||||||
|
var cb = w();
|
||||||
|
|
||||||
|
console.log("processing file at %s", filePath);
|
||||||
|
Fs.readFile(filePath, 'utf8', function (e, str) {
|
||||||
|
if (e) {
|
||||||
|
console.error(e);
|
||||||
|
return void cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTask(str, filePath, cb);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -7,6 +7,7 @@ define([
|
|||||||
'/common/sframe-common.js',
|
'/common/sframe-common.js',
|
||||||
'/customize/messages.js',
|
'/customize/messages.js',
|
||||||
'/common/common-util.js',
|
'/common/common-util.js',
|
||||||
|
'/common/common-hash.js',
|
||||||
'/common/common-interface.js',
|
'/common/common-interface.js',
|
||||||
'/common/common-thumbnail.js',
|
'/common/common-thumbnail.js',
|
||||||
'/common/common-feedback.js',
|
'/common/common-feedback.js',
|
||||||
@ -27,6 +28,7 @@ define([
|
|||||||
SFCommon,
|
SFCommon,
|
||||||
Messages,
|
Messages,
|
||||||
Util,
|
Util,
|
||||||
|
Hash,
|
||||||
UI,
|
UI,
|
||||||
Thumb,
|
Thumb,
|
||||||
Feedback,
|
Feedback,
|
||||||
@ -84,6 +86,7 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var textContentGetter;
|
||||||
var titleRecommender = function () { return false; };
|
var titleRecommender = function () { return false; };
|
||||||
var contentGetter = function () { return UNINITIALIZED; };
|
var contentGetter = function () { return UNINITIALIZED; };
|
||||||
var normalize0 = function (x) { return x; };
|
var normalize0 = function (x) { return x; };
|
||||||
@ -287,11 +290,17 @@ define([
|
|||||||
UI.removeLoadingScreen(emitResize);
|
UI.removeLoadingScreen(emitResize);
|
||||||
|
|
||||||
var privateDat = cpNfInner.metadataMgr.getPrivateData();
|
var privateDat = cpNfInner.metadataMgr.getPrivateData();
|
||||||
if (options.thumbnail && privateDat.thumbnails) {
|
|
||||||
var hash = privateDat.availableHashes.editHash ||
|
var hash = privateDat.availableHashes.editHash ||
|
||||||
privateDat.availableHashes.viewHash;
|
privateDat.availableHashes.viewHash;
|
||||||
|
var href = privateDat.pathname + '#' + hash;
|
||||||
|
if (AppConfig.textAnalyzer && textContentGetter) {
|
||||||
|
var channelId = Hash.hrefToHexChannelId(href);
|
||||||
|
AppConfig.textAnalyzer(textContentGetter, channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.thumbnail && privateDat.thumbnails) {
|
||||||
if (hash) {
|
if (hash) {
|
||||||
options.thumbnail.href = privateDat.pathname + '#' + hash;
|
options.thumbnail.href = href;
|
||||||
options.thumbnail.getContent = function () {
|
options.thumbnail.getContent = function () {
|
||||||
if (!cpNfInner.chainpad) { return; }
|
if (!cpNfInner.chainpad) { return; }
|
||||||
return cpNfInner.chainpad.getUserDoc();
|
return cpNfInner.chainpad.getUserDoc();
|
||||||
@ -567,6 +576,10 @@ define([
|
|||||||
// in the pad when requested by the framework.
|
// in the pad when requested by the framework.
|
||||||
setContentGetter: function (cg) { contentGetter = cg; },
|
setContentGetter: function (cg) { contentGetter = cg; },
|
||||||
|
|
||||||
|
// Set a text content supplier, this is a function which will give a text
|
||||||
|
// representation of the pad content if a text analyzer is configured
|
||||||
|
setTextContentGetter: function (tcg) { textContentGetter = tcg; },
|
||||||
|
|
||||||
// Inform the framework that the content of the pad has been changed locally.
|
// Inform the framework that the content of the pad has been changed locally.
|
||||||
localChange: onLocal,
|
localChange: onLocal,
|
||||||
|
|
||||||
|
|||||||
@ -402,6 +402,17 @@ define([
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
framework.setTextContentGetter(function () {
|
||||||
|
var innerCopy = inner.cloneNode(true);
|
||||||
|
displayMediaTags(framework, innerCopy, mediaTagMap);
|
||||||
|
innerCopy.normalize();
|
||||||
|
$(innerCopy).find('*').each(function (i, el) {
|
||||||
|
$(el).append(' ');
|
||||||
|
});
|
||||||
|
var str = $(innerCopy).text();
|
||||||
|
str = str.replace(/\s\s+/g, ' ');
|
||||||
|
return str;
|
||||||
|
});
|
||||||
framework.setContentGetter(function () {
|
framework.setContentGetter(function () {
|
||||||
displayMediaTags(framework, inner, mediaTagMap);
|
displayMediaTags(framework, inner, mediaTagMap);
|
||||||
inner.normalize();
|
inner.normalize();
|
||||||
|
|||||||
@ -96,6 +96,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
var addTaskUI = function (el, animate) {
|
var addTaskUI = function (el, animate) {
|
||||||
|
if (!el) { return; }
|
||||||
var $taskDiv = $('<div>', {
|
var $taskDiv = $('<div>', {
|
||||||
'class': 'cp-app-todo-task'
|
'class': 'cp-app-todo-task'
|
||||||
});
|
});
|
||||||
|
|||||||
@ -39,6 +39,24 @@ define([
|
|||||||
if (typeof(proxy.data) !== 'object') { proxy.data = {}; }
|
if (typeof(proxy.data) !== 'object') { proxy.data = {}; }
|
||||||
if (!Array.isArray(proxy.order)) { proxy.order = []; }
|
if (!Array.isArray(proxy.order)) { proxy.order = []; }
|
||||||
if (typeof(proxy.type) !== 'string') { proxy.type = 'todo'; }
|
if (typeof(proxy.type) !== 'string') { proxy.type = 'todo'; }
|
||||||
|
|
||||||
|
// if a key exists in order, but there is no data for it...
|
||||||
|
// remove that key
|
||||||
|
var i = proxy.order.length - 1;
|
||||||
|
for (;i >= 0; i--) {
|
||||||
|
if (typeof(proxy.data[proxy.order[i]]) === 'undefined') {
|
||||||
|
console.log('removing todo entry with no data at [%s]', i);
|
||||||
|
proxy.order.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if you have data, but it's not in the order array...
|
||||||
|
// add it to the order array...
|
||||||
|
Object.keys(proxy.data).forEach(function (key) {
|
||||||
|
if (proxy.order.indexOf(key) > -1) { return; }
|
||||||
|
console.log("restoring entry with missing key");
|
||||||
|
proxy.order.unshift(key);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/* add (id, obj) push id to order, add object to data */
|
/* add (id, obj) push id to order, add object to data */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user