XWiki App allowing to interact with XWiki or external apps

This commit is contained in:
Ludovic Dubost 2020-08-06 22:29:06 +02:00
parent 7b847fc6e4
commit ff9a5ea431
5 changed files with 181 additions and 1 deletions

View File

@ -12,7 +12,7 @@ define(function() {
* You should never remove the drive from this list.
*/
config.availablePadTypes = ['drive', 'teams', 'pad', 'sheet', 'code', 'slide', 'poll', 'kanban', 'whiteboard',
/*'oodoc', 'ooslide',*/ 'file', /*'todo',*/ 'contacts'];
/*'oodoc', 'ooslide',*/ 'file', /*'todo',*/ 'contacts', 'xwiki'];
/* The registered only types are apps restricted to registered users.
* You should never remove apps from this list unless you know what you're doing. The apps
* listed here by default can't work without a user account.

12
www/xwiki/index.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="no-referrer" />
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<link href="/customize/src/outer.css?ver=1.1" rel="stylesheet" type="text/css">
</head>
<body>
<iframe id="sbox-iframe">

12
www/xwiki/inner.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html class="cp-app-noscroll">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script async data-bootload="/xwiki/inner.js" data-main="/common/sframe-boot.js?ver=1.6" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
<style>
.loading-hidden { display: none; }
</style>
</head>
<body class="cp-app-xwiki">
</body>
</html>

53
www/xwiki/inner.js Normal file
View File

@ -0,0 +1,53 @@
define([
'jquery',
'/common/common-util.js',
'/common/common-hash.js',
'/bower_components/nthen/index.js',
'/common/sframe-common.js',
'/common/common-interface.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
], function (
$,
Util,
Hash,
nThen,
SFCommon,
UI
)
{
var APP = {}
window.openPicker = openPicker = function () {
var pickerCfg = {
types: [],
where: ['root']
};
common.openFilePicker(pickerCfg, function (data) {
console.log(data);
window.parent.parent.postMessage(data, '*');
});
}
var main = function () {
nThen(function (waitFor) {
$(waitFor(function () {
UI.addLoadingScreen();
var $div = $('<div>').append("");
$('body').append($div.html());
}));
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (waitFor) {
common.getSframeChannel().onReady(waitFor());
}).nThen(function (waitFor) {
// common.handleNewFile(waitFor);
}).nThen(function (/* waitFor */) {
// var metadataMgr = common.getMetadataMgr();
UI.removeLoadingScreen();
window.parent.parent.postMessage({ type: "ready" }, '*');
openPicker();
});
};
main();
});

103
www/xwiki/main.js Normal file
View File

@ -0,0 +1,103 @@
// Load #1, load as little as possible because we are in a race to get the loading screen up.
define([
'/bower_components/nthen/index.js',
'/api/config',
'/common/dom-ready.js',
'/common/requireconfig.js',
'/common/sframe-common-outer.js',
'/common/common-hash.js',
'/common/cryptget.js',
'/bower_components/hyperjson/hyperjson.js'
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO, Hash, Crypt, Hyperjson) {
var requireConfig = RequireConfig();
function receiveMessage(message) {
if (message.data.type=="get") {
console.log(message);
var opts = { initialState : '{}' };
var parsed = Hash.parsePadUrl(message.data.url);
Crypt.get(parsed.hash, function (err, val) {
if (err) {
console.log("Failed1");
}
if (!val) {
console.log("Failed2");
}
var data = JSON.parse(val);
console.log(data);
console.log(message.data);
console.log("HERE");
if (message.data.padType=="pad") {
var dom = Hyperjson.toDOM(data);
window.parent.postMessage({ content : dom.outerHTML }, '*');
} else {
window.parent.postMessage(data, '*');
}
}, opts);
} else if (message.data.type=="put") {
console.log("In pad creation");
console.log(message);
var opts = { initialState : '{}' };
var hash = Hash.createRandomHash(message.data.padType);
console.log(hash);
var data;
if (message.data.padType=="pad") {
var div = document.createElement("body")
div.innerHTML = message.data.content
data = Hyperjson.fromDOM(div);
data.push({ title: message.data.title });
} else {
data = { "title" : message.data.title, "content" : message.data.content, highlightMode: "gfm", authorMarks: {}, metadata : { "title" : message.data.title } };
}
console.log(data);
Crypt.put(hash, JSON.stringify(data), function(err, val) {
if (err) {
console.log("Failed1");
}
if (!val) {
console.log("Failed2");
}
console.log(val);
window.parent.postMessage({ href : "#" + hash }, '*');
}, opts);
}
}
window.addEventListener('message', receiveMessage);
// Loaded in load #2
nThen(function (waitFor) {
DomReady.onReady(waitFor());
}).nThen(function (waitFor) {
var req = {
cfg: requireConfig,
req: [ '/common/loading.js' ],
pfx: window.location.origin
};
window.rc = requireConfig;
window.apiconf = ApiConfig;
document.getElementById('sbox-iframe').setAttribute('src',
ApiConfig.httpSafeOrigin + '/xwiki/inner.html?' + requireConfig.urlArgs +
'#' + encodeURIComponent(JSON.stringify(req)));
// This is a cheap trick to avoid loading sframe-channel in parallel with the
// loading screen setup.
var done = waitFor();
var onMsg = function (msg) {
var data = JSON.parse(msg.data);
if (data.q !== 'READY') { return; }
window.removeEventListener('message', onMsg);
var _done = done;
done = function () { };
_done();
};
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
SFCommonO.start({
noRealtime: true,
messaging: true,
});
// window.parent.postMessage({ type: "ready2" }, '*');
});
});