mirror of https://github.com/xwiki-labs/cryptpad
Integration API: initialize an app from a Blob
This commit is contained in:
parent
8b0d80c0c4
commit
5081d5d3c0
|
@ -128,14 +128,8 @@ define([
|
|||
};
|
||||
|
||||
var importContent = UIElements.importContent = function (type, f, cfg) {
|
||||
return function () {
|
||||
var $files = $('<input>', {type:"file"});
|
||||
if (cfg && cfg.accept) {
|
||||
$files.attr('accept', cfg.accept);
|
||||
}
|
||||
$files.click();
|
||||
$files.on('change', function (e) {
|
||||
var file = e.target.files[0];
|
||||
return function (_file) {
|
||||
var todo = function (file) {
|
||||
var reader = new FileReader();
|
||||
var parsed = file && file.name && /.+\.([^.]+)$/.exec(file.name);
|
||||
var ext = parsed && parsed[1];
|
||||
|
@ -144,7 +138,19 @@ define([
|
|||
reader.readAsArrayBuffer(file, type);
|
||||
} else {
|
||||
reader.readAsText(file, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (_file) { return void todo(_file); }
|
||||
|
||||
var $files = $('<input>', {type:"file"});
|
||||
if (cfg && cfg.accept) {
|
||||
$files.attr('accept', cfg.accept);
|
||||
}
|
||||
$files.click();
|
||||
$files.on('change', function (e) {
|
||||
var file = e.target.files[0];
|
||||
todo(file);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
@ -627,12 +633,16 @@ define([
|
|||
});
|
||||
|
||||
var handler = data.first? function () {
|
||||
data.first(importer);
|
||||
data.first(function () {
|
||||
importer(); // Make sure we don't pass arguments to importer
|
||||
});
|
||||
}: importer; //importContent;
|
||||
|
||||
button
|
||||
.click(common.prepareFeedback(type))
|
||||
.click(handler);
|
||||
.click(function () {
|
||||
handler();
|
||||
});
|
||||
//}
|
||||
break;
|
||||
case 'upload':
|
||||
|
|
|
@ -71,6 +71,7 @@ define([
|
|||
var evStart = Util.mkEvent(true);
|
||||
|
||||
var mediaTagEmbedder;
|
||||
var fileImporter;
|
||||
var $embedButton;
|
||||
|
||||
var common;
|
||||
|
@ -545,7 +546,8 @@ define([
|
|||
contentUpdate(newContent, waitFor);
|
||||
}
|
||||
} else {
|
||||
if (!cpNfInner.metadataMgr.getPrivateData().isNewFile) {
|
||||
var priv = cpNfInner.metadataMgr.getPrivateData();
|
||||
if (!priv.isNewFile) {
|
||||
// We're getting 'new pad' but there is an existing file
|
||||
// We don't know exactly why this can happen but under no circumstances
|
||||
// should we overwrite the content, so lets just try again.
|
||||
|
@ -558,11 +560,16 @@ define([
|
|||
onCorruptedCache();
|
||||
return;
|
||||
}
|
||||
if (priv.initialState) {
|
||||
var blob = priv.initialState;
|
||||
var file = new File([blob], blob.name);
|
||||
UIElements.importContent('text/plain', fileImporter, {})(file);
|
||||
}
|
||||
title.updateTitle(title.defaultTitle);
|
||||
evOnDefaultContentNeeded.fire();
|
||||
}
|
||||
}).nThen(function () {
|
||||
// We have a valid chainpad, reenable cache fix in case with reconnect with
|
||||
// We have a valid chainpad, reenable cache fix in case we reconnect with
|
||||
// a corrupted cache
|
||||
noCache = false;
|
||||
|
||||
|
@ -698,31 +705,32 @@ define([
|
|||
|
||||
var setFileImporter = function (options, fi, async) {
|
||||
if (readOnly) { return; }
|
||||
toolbar.$drawer.append(
|
||||
common.createButton('import', true, options, function (c, f) {
|
||||
if (state !== STATE.READY || unsyncMode) {
|
||||
return void UI.warn(Messages.disconnected);
|
||||
}
|
||||
if (async) {
|
||||
fi(c, f, function (content) {
|
||||
nThen(function (waitFor) {
|
||||
contentUpdate(content, waitFor);
|
||||
}).nThen(function () {
|
||||
onLocal();
|
||||
});
|
||||
fileImporter = function (c, f) {
|
||||
if (state !== STATE.READY || unsyncMode) {
|
||||
return void UI.warn(Messages.disconnected);
|
||||
}
|
||||
if (async) {
|
||||
fi(c, f, function (content) {
|
||||
nThen(function (waitFor) {
|
||||
contentUpdate(content, waitFor);
|
||||
}).nThen(function () {
|
||||
onLocal();
|
||||
});
|
||||
return;
|
||||
}
|
||||
nThen(function (waitFor) {
|
||||
var content = fi(c, f);
|
||||
if (typeof(content) === "undefined") {
|
||||
return void UI.warn(Messages.importError);
|
||||
}
|
||||
contentUpdate(content, waitFor);
|
||||
}).nThen(function () {
|
||||
onLocal();
|
||||
});
|
||||
})
|
||||
return;
|
||||
}
|
||||
nThen(function (waitFor) {
|
||||
var content = fi(c, f);
|
||||
if (typeof(content) === "undefined") {
|
||||
return void UI.warn(Messages.importError);
|
||||
}
|
||||
contentUpdate(content, waitFor);
|
||||
}).nThen(function () {
|
||||
onLocal();
|
||||
});
|
||||
};
|
||||
toolbar.$drawer.append(
|
||||
common.createButton('import', true, options, fileImporter)
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@ define([
|
|||
href: href,
|
||||
useCreationScreen: !isIntegration,
|
||||
messaging: true,
|
||||
integration: isIntegration
|
||||
integration: isIntegration,
|
||||
initialState: integration.initialState || undefined
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -353,6 +353,13 @@ define([
|
|||
delete sessionStorage.CP_formExportSheet;
|
||||
}
|
||||
|
||||
// New integrated pad
|
||||
if (cfg.initialState) {
|
||||
currentPad.href = cfg.href;
|
||||
currentPad.hash = cfg.hash;
|
||||
return void todo();
|
||||
}
|
||||
|
||||
// New pad options
|
||||
var options = parsed.getOptions();
|
||||
if (options.newPadOpts) {
|
||||
|
@ -697,7 +704,6 @@ define([
|
|||
burnAfterReading: burnAfterReading,
|
||||
storeInTeam: Cryptpad.initialTeam || (Cryptpad.initialPath ? -1 : undefined),
|
||||
supportsWasm: Utils.Util.supportsWasm(),
|
||||
integration: cfg.integration
|
||||
};
|
||||
if (window.CryptPad_newSharedFolder) {
|
||||
additionalPriv.newSharedFolder = window.CryptPad_newSharedFolder;
|
||||
|
@ -718,6 +724,12 @@ define([
|
|||
additionalPriv.isChannelMuted = true;
|
||||
}
|
||||
|
||||
// Integration
|
||||
additionalPriv.integration = cfg.integration;
|
||||
additionalPriv.initialState = cfg.initialState instanceof Blob ?
|
||||
cfg.initialState : undefined;
|
||||
|
||||
// Early access
|
||||
var priv = metaObj.priv;
|
||||
var _plan = typeof(priv.plan) === "undefined" ? Utils.LocalStore.getPremium() : priv.plan;
|
||||
var p = Utils.Util.checkRestrictedApp(parsed.type, AppConfig,
|
||||
|
@ -729,6 +741,7 @@ define([
|
|||
additionalPriv.earlyAccessBlocked = true;
|
||||
}
|
||||
|
||||
// Safe apps
|
||||
if (isSafe) {
|
||||
additionalPriv.hashes = hashes;
|
||||
additionalPriv.password = password;
|
||||
|
@ -744,7 +757,7 @@ define([
|
|||
Utils.LocalStore.setPremium(metaObj.priv.plan);
|
||||
}
|
||||
|
||||
sframeChan.event('EV_METADATA_UPDATE', metaObj);
|
||||
sframeChan.event('EV_METADATA_UPDATE', metaObj, {raw: true});
|
||||
});
|
||||
};
|
||||
Cryptpad.onMetadataChanged(updateMeta);
|
||||
|
@ -1994,6 +2007,15 @@ define([
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure we add the validateKey to channel metadata when we don't use
|
||||
// the pad creation screen
|
||||
if (!rtConfig.metadata && secret.keys.validateKey) {
|
||||
rtConfig.metadata = {
|
||||
validateKey: secret.keys.validateKey
|
||||
};
|
||||
}
|
||||
|
||||
var cpNfCfg = {
|
||||
sframeChan: sframeChan,
|
||||
channel: secret.channel,
|
||||
|
@ -2021,6 +2043,8 @@ define([
|
|||
Cryptpad.getMetadata(waitFor(function (err, m) {
|
||||
cpNfCfg.owners = [m.priv.edPublic];
|
||||
}));
|
||||
} else if (isNewFile && !cfg.useCreationScreen && cfg.initialState) {
|
||||
console.log('new file with initial state provided');
|
||||
} else if (isNewFile && !cfg.useCreationScreen && currentPad.hash) {
|
||||
console.log("new file with hash in the address bar in an app without pcs and which requires owners");
|
||||
sframeChan.onReady(function () {
|
||||
|
|
|
@ -426,6 +426,9 @@ define([
|
|||
funcs.handleNewFile = function (waitFor, config) {
|
||||
if (window.__CRYPTPAD_TEST__) { return; }
|
||||
var priv = ctx.metadataMgr.getPrivateData();
|
||||
if (priv.isNewFile && priv.initialState) {
|
||||
return void setTimeout(waitFor());
|
||||
}
|
||||
if (priv.isNewFile) {
|
||||
var c = (priv.settings.general && priv.settings.general.creation) || {};
|
||||
// If this is a new file but we have a hash in the URL and pad creation screen is
|
||||
|
|
|
@ -78,11 +78,30 @@
|
|||
config.events.onSave(data);
|
||||
});
|
||||
|
||||
var onKeyValidated = function () {
|
||||
var getBlob = function (cb) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', config.document.url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function(e) {
|
||||
if (this.status == 200) {
|
||||
var blob = this.response;
|
||||
// myBlob is now the blob that the object URL pointed to.
|
||||
cb(null, blob);
|
||||
} else {
|
||||
cb(this.status);
|
||||
}
|
||||
};
|
||||
xhr.onerror = function (e) {
|
||||
cb(e.message);
|
||||
};
|
||||
xhr.send();
|
||||
};
|
||||
|
||||
var start = function (blob) {
|
||||
chan.send('START', {
|
||||
key: key,
|
||||
application: config.documentType,
|
||||
document: config.document.url,
|
||||
document: blob,
|
||||
}, function (obj) {
|
||||
if (obj && obj.error) { reject(obj.error); return console.error(obj.error); }
|
||||
console.log('OUTER START SUCCESS');
|
||||
|
@ -90,6 +109,14 @@
|
|||
});
|
||||
};
|
||||
|
||||
var onKeyValidated = function () {
|
||||
getBlob(function (err, blob) {
|
||||
if (err) { reject(err); return console.error(err); }
|
||||
blob.name = `document.${config.document.fileType}`;
|
||||
start(blob);
|
||||
});
|
||||
};
|
||||
|
||||
chan.send('GET_SESSION', {
|
||||
key: key
|
||||
}, function (obj) {
|
||||
|
@ -113,6 +140,7 @@
|
|||
* @param {object} config The object containing configuration parameters.
|
||||
* @param {object} config.document The document to load.
|
||||
* @param {string} document.url The document URL.
|
||||
* @param {string} document.fileType The document extension (md, xml, html, etc.).
|
||||
* @param {string} document.key The collaborative session key.
|
||||
* @param {object} config.events Event handlers.
|
||||
* @param {function} events.onSave The save function to store the document when edited.
|
||||
|
@ -137,7 +165,7 @@
|
|||
}
|
||||
|
||||
if (!config) { return reject('Missing args: no data provided'); }
|
||||
['document.url', 'document.key', 'documentType',
|
||||
if(['document.url', 'document.fileType', 'document.key', 'documentType',
|
||||
'events.onSave', 'events.onNewKey'].some(function (k) {
|
||||
var s = k.split('.');
|
||||
var c = config;
|
||||
|
@ -148,7 +176,7 @@
|
|||
}
|
||||
c = c[key];
|
||||
});
|
||||
});
|
||||
})) { return; }
|
||||
|
||||
cryptpadURL = cryptpadURL.replace(/(\/)+$/, '');
|
||||
var url = cryptpadURL + '/integration/';
|
||||
|
|
|
@ -99,7 +99,7 @@ define([
|
|||
isNew = true;
|
||||
return Hash.createRandomHash('integration');
|
||||
};
|
||||
var oldKey = data.sessionKey;
|
||||
var oldKey = data.key;
|
||||
if (!oldKey) { return void cb({ key: getHash() }); }
|
||||
|
||||
checkSession(oldKey, function (obj) {
|
||||
|
@ -112,33 +112,17 @@ define([
|
|||
|
||||
chan.on('START', function (data) {
|
||||
console.warn('INNER START', data);
|
||||
nThen(function (w) {
|
||||
if (!isNew) { return; }
|
||||
|
||||
// XXX initial content TBD
|
||||
var content = JSON.stringify({
|
||||
content: data.document,
|
||||
highlightMode: "gfm"
|
||||
}); // XXX only for code
|
||||
|
||||
console.error('CRYPTPUT', data.key);
|
||||
Crypt.put(data.key, content, w(), {
|
||||
metadata: {
|
||||
selfdestruct: true
|
||||
}
|
||||
});
|
||||
}).nThen(function () {
|
||||
var href = Hash.hashToHref(data.key, data.application);
|
||||
console.error(Hash.hrefToHexChannelId(href));
|
||||
window.CP_integration_outer = {
|
||||
pathname: `/${data.application}/`,
|
||||
hash: data.key,
|
||||
href: href
|
||||
};
|
||||
require(['/common/sframe-app-outer.js'], function () {
|
||||
console.warn('SAO REQUIRED');
|
||||
delete window.CP_integration_outer;
|
||||
});
|
||||
var href = Hash.hashToHref(data.key, data.application);
|
||||
console.error(Hash.hrefToHexChannelId(href));
|
||||
window.CP_integration_outer = {
|
||||
pathname: `/${data.application}/`,
|
||||
hash: data.key,
|
||||
href: href,
|
||||
initialState: isNew ? data.document : undefined
|
||||
};
|
||||
require(['/common/sframe-app-outer.js'], function () {
|
||||
console.warn('SAO REQUIRED');
|
||||
delete window.CP_integration_outer;
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue