Merge branch 'staging' of github.com:xwiki-labs/cryptpad into staging

This commit is contained in:
yflory
2017-09-13 16:20:26 +02:00
34 changed files with 245 additions and 88 deletions

View File

@@ -1,33 +1,50 @@
/*@flow*/
/*:: const define = () => {}; */
define([
'/api/config',
'/bower_components/less/dist/less.min.js'
], function (Config, Less) { /*::});module.exports = (function() {
'/api/config'
], function (Config) { /*::});module.exports = (function() {
const Config = (undefined:any);
const Less = (undefined:any);
*/
var module = { exports: {} };
var key = Config.requireConf.urlArgs;
var localStorage;
var localStorage = {};
try {
localStorage = window.localStorage || {};
if (localStorage['LESS_CACHE'] !== key) {
Object.keys(localStorage).forEach(function (k) {
if (k.indexOf('LESS_CACHE|') !== 0) { return; }
delete localStorage[k];
});
localStorage['LESS_CACHE'] = key;
}
} catch (e) {
console.error(e);
localStorage = {};
}
var fixURL = function (url) {
var mark = (url.indexOf('?') !== -1) ? '&' : '?';
return url + mark + key;
var cacheGet = function (k, cb) {
if (window.cryptpadCache) { return void window.cryptpadCache.get(k, cb); }
setTimeout(function () { cb(localStorage['LESS_CACHE|' + key + '|' + k]); })
};
var cachePut = function (k, v, cb) {
if (window.cryptpadCache) { return void window.cryptpadCache.put(k, v, cb); }
cb = cb || function () { };
setTimeout(function () { localStorage['LESS_CACHE|' + key + '|' + k] = v; cb(); });
};
var doXHR = Less.FileManager.prototype.doXHR;
Less.FileManager.prototype.doXHR = function (url, type, callback, errback) {
url = fixURL(url);
//console.log("xhr: " + url);
return doXHR(url, type, callback, errback);
var fixURL = function (url, parent) {
// data: blob: etc
if (/^[a-zA-Z0-9]*:/.test(url)) { return url; }
var ua = url.split('#');
var mark = (ua[0].indexOf('?') !== -1) ? '&' : '?';
ua[0] = ua[0] + mark + key;
if (ua[0].indexOf(':') === -1 && ua[0].indexOf('/') && parent) {
ua[0] = parent.replace(/\/[^\/]*$/, '/') + ua[0];
}
var out = ua.join('#');
//console.log(url + " --> " + out);
return out;
};
var inject = function (cssText, url) {
@@ -39,31 +56,74 @@ define([
document.head.appendChild(curStyle);
};
var checkCache = function () {
if (localStorage['LESS_CACHE'] === key) { return; }
Object.keys(localStorage).forEach(function (k) {
if (k.indexOf('LESS_CACHE|') !== 0) { return; }
delete localStorage[k];
var fixAllURLs = function (source, parent) {
var urlRegEx = /@import\s*("([^"]*)"|'([^']*)')|url\s*\(\s*(\s*"([^"]*)"|'([^']*)'|[^\)]*\s*)\s*\)/ig;
var result, url;
while (!!(result = urlRegEx.exec(source))) {
url = result[3] || result[2] || result[5] || result[6] || result[4];
var newUrl = fixURL(url, parent);
var quoteLen = result[5] || result[6] ? 1 : 0;
source = source.substr(0, urlRegEx.lastIndex - url.length - quoteLen - 1)
+ newUrl + source.substr(urlRegEx.lastIndex - quoteLen - 1);
urlRegEx.lastIndex = urlRegEx.lastIndex + (newUrl.length - url.length);
}
return source;
};
var loadCSS = function (url, cb) {
var xhr = new window.XMLHttpRequest();
xhr.open("GET", fixURL(url), true);
xhr.responseType = 'text';
xhr.onload = function () {
if (/^4/.test('' + this.status)) { return cb("error loading " + url); }
cb(undefined, xhr.response);
};
xhr.send(null);
};
var lessEngine;
var getLessEngine = function (cb) {
if (lessEngine) {
cb(lessEngine);
} else {
require(['/bower_components/less/dist/less.min.js'], function (Less) {
lessEngine = Less;
var doXHR = lessEngine.FileManager.prototype.doXHR;
lessEngine.FileManager.prototype.doXHR = function (url, type, callback, errback) {
url = fixURL(url);
//console.log("xhr: " + url);
return doXHR(url, type, callback, errback);
};
cb(lessEngine);
});
}
};
var loadLess = function (url, cb) {
getLessEngine(function (less) {
less.render('@import (multiple) "' + url + '";', {}, function(err, css) {
if (err) { return void cb(err); }
cb(undefined, css.css);
}, window.less);
});
localStorage['LESS_CACHE'] = key;
};
module.exports.load = function (url /*:string*/, cb /*:()=>void*/) {
checkCache();
if (localStorage['LESS_CACHE|' + key + '|' + url]) {
inject(localStorage['LESS_CACHE|' + key + '|' + url], url);
cb();
return;
}
Less.render('@import (multiple) "' + url + '";', {}, function(err, css) {
if (err) {
console.log(err);
return;
cacheGet(url, function (css) {
if (css) {
inject(css, url);
return void cb();
}
localStorage['LESS_CACHE|' + key + '|' + url] = css.css;
inject(css.css, url);
cb();
}, window.less);
console.log('CACHE MISS ' + url);
((/\.less([\?\#].*)?$/.test(url)) ? loadLess : loadCSS)(url, function (err, css) {
var output = fixAllURLs(css, url);
cachePut(url, output);
inject(output, url);
cb();
});
});
};
return module.exports;

View File

@@ -209,7 +209,15 @@ define([
return tagger;
};
UI.alert = function (msg, cb, force) {
UI.alert = function (msg, cb, opt) {
var force = false;
if (typeof(opt) === 'object') {
force = opt.force || false;
} else if (typeof(opt) === 'boolean') {
force = opt;
opt = {};
}
cb = cb || function () {};
var message;
@@ -228,6 +236,7 @@ define([
dialog.nav(ok),
]);
if (opt.forefront) { $(frame).addClass('forefront'); }
var listener;
var close = Util.once(function () {
$(frame).fadeOut(150, function () { $(this).remove(); });

View File

@@ -1,7 +1,37 @@
// Stage 0, this gets cached which means we can't change it. boot2-sframe.js is changable.
// Note that this file is meant to be executed only inside of a sandbox iframe.
//
// IF YOU EDIT THIS FILE, bump the version (replace 1.3 in the following command with the next version.)
// grep -nr '/common/sframe-boot.js?ver=' | sed 's/:.*$//' | while read x; do \
// sed -i -e 's@/common/sframe-boot.js?ver=[^"]*@/common/sframe-boot.js?ver=1.3@' $x; done
;(function () {
var afterLoaded = function (req) {
var localStorage = {};
if (req.cfg && req.cfg.urlArgs) {
try {
localStorage = window.localStorage;
if (localStorage['CRYPTPAD_VERSION'] !== req.cfg.urlArgs) {
// new version, flush
Object.keys(localStorage).forEach(function (k) {
if (!k.indexOf('CRYPTPAD_CACHE_')) { delete localStorage[k]; }
});
localStorage['CRYPTPAD_VERSION'] = req.cfg.urlArgs;
}
} catch (e) {
console.error(e);
localStorage = {};
}
}
window.cryptpadCache = Object.freeze({
put: function (k, v, cb) {
cb = cb || function () { };
setTimeout(function () { localStorage['CRYPTPAD_CACHE_' + k] = v; cb(); });
},
get: function (k, cb) {
if (!cb) { throw new Error(); }
setTimeout(function () { cb(localStorage['CRYPTPAD_CACHE_' + k]); });
}
});
req.cfg = req.cfg || {};
if (req.pfx) {
req.cfg.onNodeCreated = function (node /*, config, module, path*/) {

View File

@@ -10,17 +10,6 @@ define(['/common/requireconfig.js'], function (RequireConfig) {
};
}
// In the event that someone clicks a link in the iframe, it's going to cause the iframe
// to navigate away from the pad which is going to be a mess. Instead we'll just reload
// the top level and then it will be simply that a link doesn't work properly.
window.onunload = function () {
window.parent.location.reload();
};
// Make sure anything which might have leaked to the localstorage is always cleaned up.
try { window.localStorage.clear(); } catch (e) { }
try { window.sessionStorage.clear(); } catch (e) { }
var mkFakeStore = function () {
var fakeStorage = {
getItem: function (k) { return fakeStorage[k]; },

View File

@@ -1,7 +1,8 @@
// This file provides the API for the channel for talking to and from the sandbox iframe.
define([
'/common/sframe-protocol.js'
], function (SFrameProtocol) {
'/common/sframe-protocol.js',
'/common/common-util.js'
], function (SFrameProtocol, Util) {
var mkTxid = function () {
return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
@@ -9,6 +10,7 @@ define([
var create = function (ow, cb, isSandbox) {
var otherWindow;
var evReady = Util.mkEvent(true);
var handlers = {};
var queries = {};
@@ -34,11 +36,13 @@ define([
delete queries[txid];
cb(undefined, data.content, msg);
};
otherWindow.postMessage(JSON.stringify({
txid: txid,
content: content,
q: q
}), '*');
evReady.reg(function () {
otherWindow.postMessage(JSON.stringify({
txid: txid,
content: content,
q: q
}), '*');
});
};
// Fire an event. channel.event('EV_SOMETHING', { args: "whatever" });
@@ -50,7 +54,9 @@ define([
if (e.indexOf('EV_') !== 0) {
throw new Error('please only use events (starting with EV_) for event messages');
}
otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
evReady.reg(function () {
otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
});
};
// Be notified on query or event. channel.on('EV_SOMETHING', function (args, reply) { ... });
@@ -106,18 +112,14 @@ define([
}, true);
// Make sure both iframes are ready
var readyHandlers = [];
chan.onReady = function (h) {
if (typeof(h) !== "function") { return; }
readyHandlers.push(h);
chan.on('EV_RPC_READY', function () { h(); });
};
chan.ready = function () {
chan.whenReg('EV_RPC_READY', function () {
chan.event('EV_RPC_READY');
});
chan.on('EV_RPC_READY', function () {
readyHandlers.forEach(function (h) { h(); });
});
};
var txid;
@@ -129,6 +131,7 @@ define([
//console.log(msg);
} else if (!otherWindow) {
otherWindow = ow;
evReady.fire();
ow.postMessage(JSON.stringify({ txid: data.txid }), '*');
cb(chan);
} else if (typeof(data.q) === 'string' && handlers[data.q]) {
@@ -149,6 +152,7 @@ define([
if (isSandbox) {
// we're in the sandbox
otherWindow = ow;
evReady.fire();
cb(chan);
}
};