Merge branch 'soon' into staging

pull/1/head
ansuz 3 years ago
commit 48ad82c4fb

@ -1,3 +1,10 @@
# WIP
* Sheet export
* most exports broken by Chrome 92, mostly fixed
* we discovered that CSV export was not working in any major browser, though it's unclear why. We've disabled CSV export in the meantime
* some new browser-specific checkup tests to make it easier to detect future regressions in the APIs needed for sheet export
# 4.9.0 # 4.9.0
## Goals and announcements ## Goals and announcements

@ -14,11 +14,15 @@ html, body {
.report { .report {
font-size: 30px; font-size: 30px;
max-width: 50%; max-width: 26em;
margin: auto; margin: auto;
padding-top: 15px; padding-top: 15px;
} }
.summary, .failure, .error, .success {
margin-bottom: 1em;
}
.pending { .pending {
border: 1px solid @cryptpad_text_col; border: 1px solid @cryptpad_text_col;
.fa { .fa {
@ -42,10 +46,18 @@ html, body {
padding: 15px; padding: 15px;
} }
table { .table-container {
td { overflow-x: auto;
padding: 5px; width: 100%;
border: 1px solid @cryptpad_text_col; table {
td {
padding: 5px;
border: 1px solid @cryptpad_text_col;
font-size: 60%;
}
td:nth-child(2) {
word-break: break-word;
}
} }
} }
@ -72,7 +84,12 @@ html, body {
color: @cryptpad_color_link; color: @cryptpad_color_link;
} }
} }
.cp-app-checkup-version {
.cp-notice-browser, .cp-notice-details, .cp-notice-other {
font-size: 70%;
}
.cp-app-checkup-version, .cp-app-checkup-browser {
text-decoration: underline; text-decoration: underline;
} }

@ -0,0 +1,36 @@
define([
], function () {
var Tools = {};
Tools.supportsSharedArrayBuffers = function () {
try {
return Object.prototype.toString.call(new window.WebAssembly.Memory({
shared: true,
initial: 0,
maximum: 0,
}).buffer) === '[object SharedArrayBuffer]';
} catch (err) {
console.error(err);
}
return false;
};
Tools.isSafari = function () {
return navigator.vendor.match(/apple/i);
};
Tools.isChrome = function () {
return navigator.vendor.match(/google/i);
};
Tools.guessBrowser = function () {
if (Tools.isChrome()) { return 'chrome/blink'; }
if (Tools.isSafari()) { return 'safari/webkit'; }
if (navigator.userAgent.match(/firefox\//i)) { return 'firefox/gecko'; }
if (navigator.userAgent.match(/edge\//i)) { return 'edge/edgehtml'; }
if (navigator.userAgent.match(/trident\//i)) { return 'ie/trident'; }
return navigator.userAgent + "\n" + navigator.vendor;
};
return Tools;
});

@ -13,13 +13,14 @@ define([
'/common/pinpad.js', '/common/pinpad.js',
'/common/outer/network-config.js', '/common/outer/network-config.js',
'/customize/pages.js', '/customize/pages.js',
'/checkup/checkup-tools.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/checkup/app-checkup.less', 'less!/checkup/app-checkup.less',
], function ($, ApiConfig, Assertions, h, Messages, DomReady, ], function ($, ApiConfig, Assertions, h, Messages, DomReady,
nThen, SFCommonO, Login, Hash, Util, Pinpad, nThen, SFCommonO, Login, Hash, Util, Pinpad,
NetConfig, Pages) { NetConfig, Pages, Tools) {
var Assert = Assertions(); var Assert = Assertions();
var trimSlashes = function (s) { var trimSlashes = function (s) {
if (typeof(s) !== 'string') { return s; } if (typeof(s) !== 'string') { return s; }
@ -703,6 +704,69 @@ define([
}); });
}); });
var safariGripe = function () {
return h('p.cp-notice-other', 'This is expected because Safari and platforms that use its engine lack commonly supported functionality.');
};
var browserIssue = function () {
return h('p.cp-notice-other', 'This test checks for the presence of features in your browser and is not necessarily caused by server misconfiguration.');
};
assert(function (cb, msg) {
cb = Util.once(cb);
setWarningClass(msg);
var notice = h('span', [
h('p', 'It appears that some features required for Office file format conversion are not present.'),
Tools.isSafari()? safariGripe(): undefined,
browserIssue(),
]);
msg.appendChild(notice);
var expected = [
'Atomics',
'SharedArrayBuffer',
'WebAssembly',
['WebAssembly', 'Memory'],
['WebAssembly', 'instantiate'],
['WebAssembly', 'instantiateStreaming'],
['Buffer', 'from'],
'SharedWorker',
'worker',
'crossOriginIsolated',
];
var responses = {};
nThen(function (w) {
deferredPostMessage({
command: 'CHECK_JS_APIS',
content: {
globals: expected,
},
}, w(function (response) {
Util.extend(responses, response);
}));
deferredPostMessage({
command: 'FANCY_API_CHECKS',
content: {
},
}, w(function (response) {
Util.extend(responses, response);
}));
}).nThen(function () {
if (!responses.Atomics || !responses.WebAssembly) {
return void cb(responses);
}
if (responses.SharedArrayBuffer || responses.SharedArrayBufferFallback) {
return cb(true);
}
return void cb(response);
});
});
var isHTTPS = function (host) { var isHTTPS = function (host) {
return /^https:\/\//.test(host); return /^https:\/\//.test(host);
}; };
@ -831,17 +895,19 @@ define([
var failureReport = function (obj) { var failureReport = function (obj) {
var printableValue = obj.output; var printableValue = obj.output;
try { try {
printableValue = JSON.stringify(obj.output); printableValue = JSON.stringify(obj.output, null, ' ');
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
return h('div.error', [ return h('div.error', [
h('h5', obj.message), h('h5', obj.message),
h('table', [ h('div.table-container',
row(["Failed test number", obj.test + 1]), h('table', [
row(["Returned value", code(printableValue)]), row(["Failed test number", obj.test + 1]),
]), row(["Returned value", h('pre', code(printableValue))]),
]),
),
]); ]);
}; };
@ -849,7 +915,7 @@ define([
var $progress = $('#cp-progress'); var $progress = $('#cp-progress');
var versionStatement = function () { var versionStatement = function () {
return h('p', [ return h('p.cp--notice-version', [
"This instance is running ", "This instance is running ",
h('span.cp-app-checkup-version',[ h('span.cp-app-checkup-version',[
"CryptPad", "CryptPad",
@ -860,6 +926,16 @@ define([
]); ]);
}; };
var browserStatement = function () {
var name = Tools.guessBrowser();
if (!name) { return; }
return h('p.cp-notice-browser', [
"You appear to be using a ",
h('span.cp-app-checkup-browser', name),
' browser to view this page.',
]);
};
Assert.run(function (state) { Assert.run(function (state) {
var errors = state.errors; var errors = state.errors;
var failed = errors.length; var failed = errors.length;
@ -870,10 +946,11 @@ define([
var failedDetails = "Details found below"; var failedDetails = "Details found below";
var successDetails = "This checkup only tests the most common configuration issues. You may still experience errors or incorrect behaviour."; var successDetails = "This checkup only tests the most common configuration issues. You may still experience errors or incorrect behaviour.";
var details = h('p', failed? failedDetails: successDetails); var details = h('p.cp-notice-details', failed? failedDetails: successDetails);
var summary = h('div.summary.' + statusClass, [ var summary = h('div.summary.' + statusClass, [
versionStatement(), versionStatement(),
browserStatement(),
h('p', Messages._getKey('assert_numberOfTestsPassed', [ h('p', Messages._getKey('assert_numberOfTestsPassed', [
state.passed, state.passed,
state.total state.total

@ -1,10 +1,12 @@
define([ define([
'jquery', 'jquery',
'/common/common-util.js',
'/checkup/checkup-tools.js',
'/bower_components/tweetnacl/nacl-fast.min.js', '/bower_components/tweetnacl/nacl-fast.min.js',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/checkup/app-checkup.less', 'less!/checkup/app-checkup.less',
], function ($) { ], function ($, Util, Tools) {
var postMessage = function (content) { var postMessage = function (content) {
window.parent.postMessage(JSON.stringify(content), '*'); window.parent.postMessage(JSON.stringify(content), '*');
}; };
@ -26,6 +28,26 @@ define([
}); });
}; };
COMMANDS.CHECK_JS_APIS = function (content, cb) {
var globalAPIs = content['globals'] || [];
var response = {};
globalAPIs.forEach(function (key) {
if (Array.isArray(key)) {
response[key.join('.')] = Boolean(Util.find(window, key));
return;
}
response[key] = Boolean(window[key]);
});
cb(response);
};
COMMANDS.FANCY_API_CHECKS = function (content, cb) {
cb({
SharedArrayBufferFallback: Tools.supportsSharedArrayBuffers(),
});
};
window.addEventListener("message", function (event) { window.addEventListener("message", function (event) {
var txid, command; var txid, command;
if (event && event.data) { if (event && event.data) {

@ -72,8 +72,31 @@ define([
return JSONSortify(obj); return JSONSortify(obj);
}; };
/* Chrome 92 dropped support for SharedArrayBuffer in cross-origin contexts
where window.crossOriginIsolated is false.
Their blog (https://blog.chromium.org/2021/02/restriction-on-sharedarraybuffers.html)
isn't clear about why they're doing this, but since it's related to site-isolation
it seems they're trying to do vague security things.
In any case, there seems to be a workaround where you can still create them
by using `new WebAssembly.Memory({shared: true, ...})` instead of `new SharedArrayBuffer`.
This seems unreliable, but it's better than not being able to export, since
we actively rely on postMessage between iframes and therefore can't afford
to opt for full isolation.
*/
var supportsSharedArrayBuffers = function () {
try {
return Object.prototype.toString.call(new window.WebAssembly.Memory({shared: true, initial: 0, maximum: 0}).buffer) === '[object SharedArrayBuffer]';
} catch (err) {
console.error(err);
}
return false;
};
var supportsXLSX = function () { var supportsXLSX = function () {
return !(typeof(Atomics) === "undefined" || typeof (SharedArrayBuffer) === "undefined" || typeof(WebAssembly) === 'undefined'); return !(typeof(Atomics) === "undefined" || !supportsSharedArrayBuffers() /* || typeof (SharedArrayBuffer) === "undefined" */ || typeof(WebAssembly) === 'undefined');
}; };
@ -1915,7 +1938,9 @@ define([
var exportXLSXFile = function() { var exportXLSXFile = function() {
var text = getContent(); var text = getContent();
var suggestion = Title.suggestTitle(Title.defaultTitle); var suggestion = Title.suggestTitle(Title.defaultTitle);
var ext = ['.xlsx', '.ods', '.bin', '.csv', '.pdf']; var ext = ['.xlsx', '.ods', '.bin',
//'.csv', // XXX
'.pdf'];
var type = common.getMetadataMgr().getPrivateData().ooType; var type = common.getMetadataMgr().getPrivateData().ooType;
var warning = ''; var warning = '';
if (type==="presentation") { if (type==="presentation") {

@ -1,3 +1,8 @@
function SUPPORTS_SHARED_MEMORY() {
return typeof(SharedArrayBuffer) !== 'undefined';
}
// Support for growable heap + pthreads, where the buffer may change, so JS views // Support for growable heap + pthreads, where the buffer may change, so JS views
// must be updated. // must be updated.
function GROWABLE_HEAP_STORE_I8(ptr, value) { function GROWABLE_HEAP_STORE_I8(ptr, value) {
@ -1030,7 +1035,7 @@ if (ENVIRONMENT_IS_PTHREAD) {
"maximum": 1073741824 / WASM_PAGE_SIZE, "maximum": 1073741824 / WASM_PAGE_SIZE,
"shared": true "shared": true
}); });
if (!(wasmMemory.buffer instanceof SharedArrayBuffer)) { if (Object.prototype.toString.call(wasmMemory.buffer) !== '[object SharedArrayBuffer]') {
err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag"); err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag");
if (ENVIRONMENT_HAS_NODE) { if (ENVIRONMENT_HAS_NODE) {
console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)"); console.log("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and also use a recent version)");
@ -2161,7 +2166,7 @@ var PThread = {
}), }),
receiveObjectTransfer: (function(data) {}), receiveObjectTransfer: (function(data) {}),
allocateUnusedWorkers: (function(numWorkers, onFinishedLoading) { allocateUnusedWorkers: (function(numWorkers, onFinishedLoading) {
if (typeof SharedArrayBuffer === "undefined") return; if (!SUPPORTS_SHARED_MEMORY()) return;
var workers = []; var workers = [];
var numWorkersToCreate = numWorkers; var numWorkersToCreate = numWorkers;
if (PThread.preallocatedWorkers.length > 0) { if (PThread.preallocatedWorkers.length > 0) {
@ -2276,7 +2281,7 @@ var PThread = {
} }
}), }),
createNewWorkers: (function(numWorkers) { createNewWorkers: (function(numWorkers) {
if (typeof SharedArrayBuffer === "undefined") return []; if (!SUPPORTS_SHARED_MEMORY()) return [];
var pthreadMainJs = "x2t.worker.js"; var pthreadMainJs = "x2t.worker.js";
pthreadMainJs = locateFile(pthreadMainJs); pthreadMainJs = locateFile(pthreadMainJs);
var newWorkers = []; var newWorkers = [];
@ -5683,7 +5688,7 @@ function _emscripten_get_sbrk_ptr() {
} }
Module["_emscripten_get_sbrk_ptr"] = _emscripten_get_sbrk_ptr; Module["_emscripten_get_sbrk_ptr"] = _emscripten_get_sbrk_ptr;
function _emscripten_has_threading_support() { function _emscripten_has_threading_support() {
return typeof SharedArrayBuffer !== "undefined"; return SUPPORTS_SHARED_MEMORY();
} }
Module["_emscripten_has_threading_support"] = _emscripten_has_threading_support; Module["_emscripten_has_threading_support"] = _emscripten_has_threading_support;
function _emscripten_is_main_browser_thread() { function _emscripten_is_main_browser_thread() {
@ -6761,7 +6766,7 @@ function _pthread_self() {
} }
Module["_pthread_self"] = _pthread_self; Module["_pthread_self"] = _pthread_self;
function _pthread_create(pthread_ptr, attr, start_routine, arg) { function _pthread_create(pthread_ptr, attr, start_routine, arg) {
if (typeof SharedArrayBuffer === "undefined") { if (!SUPPORTS_SHARED_MEMORY()) {
err("Current environment does not support SharedArrayBuffer, pthreads are not available!"); err("Current environment does not support SharedArrayBuffer, pthreads are not available!");
return 6; return 6;
} }

@ -560,7 +560,7 @@
"form_form": "フォーム", "form_form": "フォーム",
"form_editor": "エディタ", "form_editor": "エディタ",
"form_delete": "削除", "form_delete": "削除",
"form_sent": "送信しました", "form_sent": "回答を送信しました",
"form_reset": "リセット", "form_reset": "リセット",
"form_update": "更新", "form_update": "更新",
"form_submit": "送信", "form_submit": "送信",
@ -1378,5 +1378,6 @@
"notification_linkShared": "{0}があなたとリンクを共有しました: <b>{1}</b>", "notification_linkShared": "{0}があなたとリンクを共有しました: <b>{1}</b>",
"fm_link_name_placeholder": "あなたのリンク", "fm_link_name_placeholder": "あなたのリンク",
"fm_link_warning": "注意URLが200字を超えています", "fm_link_warning": "注意URLが200字を超えています",
"fm_link_invalid": "URLが無効です" "fm_link_invalid": "URLが無効です",
"form_answerAs": "名前を記入してください"
} }

Loading…
Cancel
Save