Fix SharedArrayBuffer cross-origin issues for X2T

pull/1/head
yflory 3 years ago
parent 1e12b85b7c
commit d547c90168

@ -20,6 +20,7 @@ define([
'/common/onlyoffice/oodoc_base.js', '/common/onlyoffice/oodoc_base.js',
'/common/onlyoffice/ooslide_base.js', '/common/onlyoffice/ooslide_base.js',
'/common/outer/worker-channel.js', '/common/outer/worker-channel.js',
'/common/outer/x2t.js',
'/bower_components/file-saver/FileSaver.min.js', '/bower_components/file-saver/FileSaver.min.js',
@ -47,7 +48,8 @@ define([
EmptyCell, EmptyCell,
EmptyDoc, EmptyDoc,
EmptySlide, EmptySlide,
Channel) Channel,
X2T)
{ {
var saveAs = window.saveAs; var saveAs = window.saveAs;
var Nacl = window.nacl; var Nacl = window.nacl;
@ -60,7 +62,7 @@ define([
var DISPLAY_RESTORE_BUTTON = false; var DISPLAY_RESTORE_BUTTON = false;
var NEW_VERSION = 4; var NEW_VERSION = 4;
var PENDING_TIMEOUT = 30000; var PENDING_TIMEOUT = 30000;
var CURRENT_VERSION = 'v4'; var CURRENT_VERSION = X2T.CURRENT_VERSION;
//var READONLY_REFRESH_TO = 15000; //var READONLY_REFRESH_TO = 15000;
var debug = function (x, type) { var debug = function (x, type) {
@ -1699,239 +1701,81 @@ define([
makeChannel(); makeChannel();
}; };
var x2tReady = Util.mkEvent(true); var x2tConvertData = function (data, fileName, format, cb) {
var fetchFonts = function (x2t) { var sframeChan = common.getSframeChannel();
var path = '/common/onlyoffice/'+CURRENT_VERSION+'/fonts/';
var e = getEditor(); var e = getEditor();
var fonts = e.FontLoader.fontInfos; var fonts = e.FontLoader.fontInfos;
var files = e.FontLoader.fontFiles; var files = e.FontLoader.fontFiles.map(function (f) {
var suffixes = { return { 'Id': f.Id, };
indexR: '',
indexB: '_Bold',
indexBI: '_Bold_Italic',
indexI: '_Italic',
};
nThen(function (waitFor) {
fonts.forEach(function (font) {
// Check if the font is already loaded
if (!font.NeedStyles) { return; }
// Pick the variants we need (regular, bold, italic)
['indexR', 'indexB', 'indexI', 'indexBI'].forEach(function (k) {
if (typeof(font[k]) !== "number" || font[k] === -1) { return; } // No matching file
var file = files[font[k]];
var name = font.Name + suffixes[k] + '.ttf';
Util.fetch(path + file.Id, waitFor(function (err, buffer) {
if (buffer) {
x2t.FS.writeFile('/working/fonts/' + name, buffer);
}
}));
});
});
}).nThen(function () {
x2tReady.fire();
}); });
}; var type = common.getMetadataMgr().getPrivateData().ooType;
sframeChan.query('Q_OO_CONVERT', {
var x2tInitialized = false; data: data,
var x2tInit = function(x2t) { type: type,
debug("x2t mount"); fileName: fileName,
// x2t.FS.mount(x2t.MEMFS, {} , '/'); outputFormat: format,
x2t.FS.mkdir('/working'); images: window.frames[0].AscCommon.g_oDocumentUrls.urls || {},
x2t.FS.mkdir('/working/media'); fonts: fonts,
x2t.FS.mkdir('/working/fonts'); fonts_files: files,
x2tInitialized = true; mediasSources: getMediasSources(),
fetchFonts(x2t); mediasData: mediasData
debug("x2t mount done"); }, function (err, obj) {
}; if (err || !obj || !obj.data) {
var getX2T = function (cb) { UI.warn(Messages.error);
// Perform the x2t conversion cb();
require(['/common/onlyoffice/x2t/x2t.js'], function() { // FIXME why does this fail without an access-control-allow-origin header?
var x2t = window.Module;
x2t.run();
if (x2tInitialized) {
debug("x2t runtime already initialized");
return void x2tReady.reg(function () {
cb(x2t);
});
}
x2t.onRuntimeInitialized = function() {
debug("x2t in runtime initialized");
// Init x2t js module
x2tInit(x2t);
x2tReady.reg(function () {
cb(x2t);
});
};
});
};
/*
Converting Data
This function converts a data in a specific format to the outputformat
The filename extension needs to represent the input format
Example: fileName=cryptpad.bin outputFormat=xlsx
*/
var getFormatId = function (ext) {
// Sheets
if (ext === 'xlsx') { return 257; }
if (ext === 'xls') { return 258; }
if (ext === 'ods') { return 259; }
if (ext === 'csv') { return 260; }
if (ext === 'pdf') { return 513; }
return;
};
var getFromId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatFrom>'+id+'</m_nFormatFrom>';
};
var getToId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatTo>'+id+'</m_nFormatTo>';
};
var x2tConvertDataInternal = function(x2t, data, fileName, outputFormat) {
debug("Converting Data for " + fileName + " to " + outputFormat);
// PDF
var pdfData = '';
if (outputFormat === "pdf" && typeof(data) === "object" && data.bin && data.buffer) {
// Add conversion rules
pdfData = "<m_bIsNoBase64>false</m_bIsNoBase64>" +
"<m_sFontDir>/working/fonts/</m_sFontDir>";
// writing file to mounted working disk (in memory)
x2t.FS.writeFile('/working/' + fileName, data.bin);
x2t.FS.writeFile('/working/pdf.bin', data.buffer);
} else {
// writing file to mounted working disk (in memory)
x2t.FS.writeFile('/working/' + fileName, data);
}
// Adding images
Object.keys(window.frames[0].AscCommon.g_oDocumentUrls.urls || {}).forEach(function (_mediaFileName) {
var mediaFileName = _mediaFileName.substring(6);
var mediasSources = getMediasSources();
var mediaSource = mediasSources[mediaFileName];
var mediaData = mediaSource ? mediasData[mediaSource.src] : undefined;
if (mediaData) {
debug("Writing media data " + mediaFileName);
debug("Data");
var fileData = mediaData.content;
x2t.FS.writeFile('/working/media/' + mediaFileName, new Uint8Array(fileData));
} else {
debug("Could not find media content for " + mediaFileName);
} }
cb(obj.data, obj.images);
}, {
raw: true
}); });
var inputFormat = fileName.split('.').pop();
var params = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<TaskQueueDataConvert xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
+ "<m_sFileFrom>/working/" + fileName + "</m_sFileFrom>"
+ "<m_sFileTo>/working/" + fileName + "." + outputFormat + "</m_sFileTo>"
+ pdfData
+ getFromId(inputFormat)
+ getToId(outputFormat)
+ "<m_bIsNoBase64>false</m_bIsNoBase64>"
+ "</TaskQueueDataConvert>";
// writing params file to mounted working disk (in memory)
x2t.FS.writeFile('/working/params.xml', params);
// running conversion
x2t.ccall("runX2T", ["number"], ["string"], ["/working/params.xml"]);
// reading output file from working disk (in memory)
var result;
try {
result = x2t.FS.readFile('/working/' + fileName + "." + outputFormat);
} catch (e) {
debug("Failed reading converted file");
UI.removeModals();
UI.warn(Messages.error);
return "";
}
return result;
}; };
APP.printPdf = function (obj, cb) { APP.printPdf = function (obj, cb) {
getX2T(function (x2t) { var bin = getContent();
//var e = getEditor(); x2tConvertData({
//var d = e.asc_nativePrint(undefined, undefined, 0x100 + opts.printType).ImData; buffer: obj.data,
var bin = getContent(); bin: bin
var xlsData = x2tConvertDataInternal(x2t, { }, 'output.bin', 'pdf', function (xlsData) {
buffer: obj.data, if (!xlsData) { return; }
bin: bin var md = common.getMetadataMgr().getMetadataLazy();
}, 'output.bin', 'pdf'); var type = common.getMetadataMgr().getPrivateData().ooType;
if (xlsData) { var title = md.title || md.defaultTitle || type;
var md = common.getMetadataMgr().getMetadataLazy(); var blob = new Blob([xlsData], {type: "application/pdf"});
var type = common.getMetadataMgr().getPrivateData().ooType; saveAs(blob, title+'.pdf');
var title = md.title || md.defaultTitle || type; cb({
var blob = new Blob([xlsData], {type: "application/pdf"}); "type":"save",
//var url = URL.createObjectURL(blob, { type: "application/pdf" }); "status":"ok",
saveAs(blob, title+'.pdf'); });
//window.open(url);
cb({
"type":"save",
"status":"ok",
//"data":url + "?disposition=inline&ooname=output.pdf"
});
/*
ooChannel.send({
"type":"documentOpen",
"data": {
"type":"save",
"status":"ok",
"data":url + "?disposition=inline&ooname=output.pdf"
}
});
*/
}
}); });
}; };
var x2tSaveAndConvertDataInternal = function(x2t, data, filename, extension, finalFilename) { var x2tSaveAndConvertData = function(data, filename, extension, finalFilename) {
var type = common.getMetadataMgr().getPrivateData().ooType; var type = common.getMetadataMgr().getPrivateData().ooType;
var xlsData;
// PDF // PDF
if (type === "sheet" && extension === "pdf") { if (type === "sheet" && extension === "pdf") {
var e = getEditor(); var e = getEditor();
var d = e.asc_nativePrint(undefined, undefined, 0x101).ImData; var d = e.asc_nativePrint(undefined, undefined, 0x101).ImData;
xlsData = x2tConvertDataInternal(x2t, { x2tConvertData({
buffer: d.data, buffer: d.data,
bin: data bin: data
}, filename, extension); }, filename, extension, function (res) {
if (res) {
var _blob = new Blob([res], {type: "application/bin;charset=utf-8"});
UI.removeModals();
saveAs(_blob, finalFilename);
}
});
return;
}
x2tConvertData(data, filename, extension, function (xlsData) {
if (xlsData) { if (xlsData) {
var _blob = new Blob([xlsData], {type: "application/bin;charset=utf-8"}); var blob = new Blob([xlsData], {type: "application/bin;charset=utf-8"});
UI.removeModals(); UI.removeModals();
saveAs(_blob, finalFilename); saveAs(blob, finalFilename);
return;
} }
return; UI.warn(Messages.error);
}
if (type === "sheet" && extension !== 'xlsx') {
xlsData = x2tConvertDataInternal(x2t, data, filename, 'xlsx');
filename += '.xlsx';
} else if (type === "presentation" && extension !== "pptx") {
xlsData = x2tConvertDataInternal(x2t, data, filename, 'pptx');
filename += '.pptx';
} else if (type === "doc" && extension !== "docx") {
xlsData = x2tConvertDataInternal(x2t, data, filename, 'docx');
filename += '.docx';
}
xlsData = x2tConvertDataInternal(x2t, data, filename, extension);
if (xlsData) {
var blob = new Blob([xlsData], {type: "application/bin;charset=utf-8"});
UI.removeModals();
saveAs(blob, finalFilename);
}
};
var x2tSaveAndConvertData = function(data, filename, extension, finalName) {
getX2T(function (x2t) {
x2tSaveAndConvertDataInternal(x2t, data, filename, extension, finalName);
}); });
}; };
@ -2004,32 +1848,29 @@ define([
$select.find('button').addClass('btn'); $select.find('button').addClass('btn');
}; };
var x2tImportImagesInternal = function(x2t, images, i, callback) { var x2tImportImagesInternal = function(images, i, callback) {
if (i >= images.length) { if (i >= images.length) {
callback(); callback();
} else { } else {
debug("Import image " + i); debug("Import image " + i);
var handleFileData = { var handleFileData = {
name: images[i], name: images[i].name,
mediasSources: getMediasSources(), mediasSources: getMediasSources(),
callback: function() { callback: function() {
debug("next image"); debug("next image");
x2tImportImagesInternal(x2t, images, i+1, callback); x2tImportImagesInternal(images, i+1, callback);
}, },
}; };
var filePath = "/working/media/" + images[i]; var fileData = images[i].data;
debug("Import filename " + filePath);
var fileData = x2t.FS.readFile("/working/media/" + images[i], { encoding : "binary" });
debug("Importing data");
debug("Buffer"); debug("Buffer");
debug(fileData.buffer); debug(fileData.buffer);
var blob = new Blob([fileData.buffer], {type: 'image/png'}); var blob = new Blob([fileData.buffer], {type: 'image/png'});
blob.name = images[i]; blob.name = images[i].name;
APP.FMImages.handleFile(blob, handleFileData); APP.FMImages.handleFile(blob, handleFileData);
} }
}; };
var x2tImportImages = function (x2t, callback) { var x2tImportImages = function (images, callback) {
if (!APP.FMImages) { if (!APP.FMImages) {
var fmConfigImages = { var fmConfigImages = {
noHandlers: true, noHandlers: true,
@ -2055,14 +1896,8 @@ define([
// Import Images // Import Images
debug("Import Images"); debug("Import Images");
var files = x2t.FS.readdir("/working/media/"); debug(images);
var images = []; x2tImportImagesInternal(images, 0, function() {
files.forEach(function (file) {
if (file !== "." && file !== "..") {
images.push(file);
}
});
x2tImportImagesInternal(x2t, images, 0, function() {
debug("Sync media sources elements"); debug("Sync media sources elements");
debug(getMediasSources()); debug(getMediasSources());
APP.onLocal(); APP.onLocal();
@ -2072,26 +1907,12 @@ define([
}; };
var x2tConvertData = function (x2t, data, filename, extension, callback) { var x2tImportData = function (data, filename, extension, callback) {
var convertedContent; x2tConvertData(new Uint8Array(data), filename, extension, function (binData, images) {
// Convert from ODF format: if (!binData) { return void UI.warn(Messages.error); }
// first convert to Office format then to the selected extension x2tImportImages(images, function() {
if (filename.endsWith(".ods")) { callback(binData);
console.log(x2t, data, filename, extension); });
convertedContent = x2tConvertDataInternal(x2t, new Uint8Array(data), filename, "xlsx");
console.log(convertedContent);
convertedContent = x2tConvertDataInternal(x2t, convertedContent, filename + ".xlsx", extension);
} else if (filename.endsWith(".odt")) {
convertedContent = x2tConvertDataInternal(x2t, new Uint8Array(data), filename, "docx");
convertedContent = x2tConvertDataInternal(x2t, convertedContent, filename + ".docx", extension);
} else if (filename.endsWith(".odp")) {
convertedContent = x2tConvertDataInternal(x2t, new Uint8Array(data), filename, "pptx");
convertedContent = x2tConvertDataInternal(x2t, convertedContent, filename + ".pptx", extension);
} else {
convertedContent = x2tConvertDataInternal(x2t, new Uint8Array(data), filename, extension);
}
x2tImportImages(x2t, function() {
callback(convertedContent);
}); });
}; };
@ -2145,10 +1966,8 @@ define([
]); ]);
UI.openCustomModal(UI.dialog.customModal(div, {buttons: []})); UI.openCustomModal(UI.dialog.customModal(div, {buttons: []}));
setTimeout(function () { setTimeout(function () {
getX2T(function (x2t) { x2tImportData(new Uint8Array(content), filename.name, "bin", function(c) {
x2tConvertData(x2t, new Uint8Array(content), filename.name, "bin", function(c) { importFile(c);
importFile(c);
});
}); });
}, 100); }, 100);
}; };

@ -143,6 +143,22 @@ define([
} }
sframeChan.event('EV_OO_EVENT', obj); sframeChan.event('EV_OO_EVENT', obj);
}); });
// X2T
var x2t;
var onConvert = function (obj, cb) {
x2t.convert(obj, cb);
};
sframeChan.on('Q_OO_CONVERT', function (obj, cb) {
if (x2t) { return void onConvert(obj, cb); }
require(['/common/outer/x2t.js'], function (X2T) {
x2t = X2T.start();
onConvert(obj, cb);
});
});
}; };
SFCommonO.start({ SFCommonO.start({
hash: hash, hash: hash,

@ -0,0 +1,243 @@
define([
'/bower_components/nthen/index.js',
'/common/common-util.js',
], function (nThen, Util) {
var X2T = {};
var CURRENT_VERSION = X2T.CURRENT_VERSION = 'v4';
var debug = function (str) {
if (localStorage.CryptPad_dev !== "1") { return; }
console.debug(str);
};
X2T.start = function () {
var x2tReady = Util.mkEvent(true);
var fetchFonts = function (x2t, obj, cb) {
if (!obj.fonts) { return void cb(); }
var path = '/common/onlyoffice/'+CURRENT_VERSION+'/fonts/';
var fonts = obj.fonts;
var files = obj.fonts_files;
var suffixes = {
indexR: '',
indexB: '_Bold',
indexBI: '_Bold_Italic',
indexI: '_Italic',
};
nThen(function (waitFor) {
fonts.forEach(function (font) {
// Check if the font is already loaded
if (!font.NeedStyles) { return; }
// Pick the variants we need (regular, bold, italic)
['indexR', 'indexB', 'indexI', 'indexBI'].forEach(function (k) {
if (typeof(font[k]) !== "number" || font[k] === -1) { return; } // No matching file
var file = files[font[k]];
var name = font.Name + suffixes[k] + '.ttf';
Util.fetch(path + file.Id, waitFor(function (err, buffer) {
if (buffer) {
x2t.FS.writeFile('/working/fonts/' + name, buffer);
}
}));
});
});
}).nThen(function () {
cb();
});
};
var x2tInitialized = false;
var x2tInit = function(x2t) {
debug("x2t mount");
// x2t.FS.mount(x2t.MEMFS, {} , '/');
x2t.FS.mkdir('/working');
x2t.FS.mkdir('/working/media');
x2t.FS.mkdir('/working/fonts');
x2tInitialized = true;
x2tReady.fire();
debug("x2t mount done");
};
var getX2T = function (cb) {
// Perform the x2t conversion
require(['/common/onlyoffice/x2t/x2t.js'], function() { // FIXME why does this fail without an access-control-allow-origin header?
var x2t = window.Module;
x2t.run();
if (x2tInitialized) {
debug("x2t runtime already initialized");
return void x2tReady.reg(function () {
cb(x2t);
});
}
x2t.onRuntimeInitialized = function() {
debug("x2t in runtime initialized");
// Init x2t js module
x2tInit(x2t);
x2tReady.reg(function () {
cb(x2t);
});
};
});
};
var getFormatId = function (ext) {
// Sheets
if (ext === 'xlsx') { return 257; }
if (ext === 'xls') { return 258; }
if (ext === 'ods') { return 259; }
if (ext === 'csv') { return 260; }
if (ext === 'pdf') { return 513; }
// Docs
if (ext === 'docx') { return 65; }
if (ext === 'doc') { return 66; }
if (ext === 'odt') { return 67; }
if (ext === 'txt') { return 69; }
if (ext === 'html') { return 70; }
// Slides
if (ext === 'pptx') { return 129; }
if (ext === 'ppt') { return 130; }
if (ext === 'odp') { return 131; }
return;
};
var getFromId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatFrom>'+id+'</m_nFormatFrom>';
};
var getToId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatTo>'+id+'</m_nFormatTo>';
};
var x2tConvertDataInternal = function(x2t, obj) {
var data = obj.data;
var fileName = obj.fileName;
var outputFormat = obj.outputFormat;
var images = obj.images;
debug("Converting Data for " + fileName + " to " + outputFormat);
// PDF
var pdfData = '';
if (outputFormat === "pdf" && typeof(data) === "object" && data.bin && data.buffer) {
// Add conversion rules
pdfData = "<m_bIsNoBase64>false</m_bIsNoBase64>" +
"<m_sFontDir>/working/fonts/</m_sFontDir>";
// writing file to mounted working disk (in memory)
x2t.FS.writeFile('/working/' + fileName, data.bin);
x2t.FS.writeFile('/working/pdf.bin', data.buffer);
} else {
// writing file to mounted working disk (in memory)
x2t.FS.writeFile('/working/' + fileName, data);
}
// Adding images
Object.keys(images || {}).forEach(function (_mediaFileName) {
var mediaFileName = _mediaFileName.substring(6);
var mediasSources = obj.mediasSources || {};
var mediasData = obj.mediasData || {};
var mediaSource = mediasSources[mediaFileName];
var mediaData = mediaSource ? mediasData[mediaSource.src] : undefined;
if (mediaData) {
debug("Writing media data " + mediaFileName);
debug("Data");
var fileData = mediaData.content;
x2t.FS.writeFile('/working/media/' + mediaFileName, new Uint8Array(fileData));
} else {
debug("Could not find media content for " + mediaFileName);
}
});
var inputFormat = fileName.split('.').pop();
var params = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<TaskQueueDataConvert xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
+ "<m_sFileFrom>/working/" + fileName + "</m_sFileFrom>"
+ "<m_sFileTo>/working/" + fileName + "." + outputFormat + "</m_sFileTo>"
+ pdfData
+ getFromId(inputFormat)
+ getToId(outputFormat)
+ "<m_bIsNoBase64>false</m_bIsNoBase64>"
+ "</TaskQueueDataConvert>";
// writing params file to mounted working disk (in memory)
x2t.FS.writeFile('/working/params.xml', params);
// running conversion
x2t.ccall("runX2T", ["number"], ["string"], ["/working/params.xml"]);
// reading output file from working disk (in memory)
var result;
try {
result = x2t.FS.readFile('/working/' + fileName + "." + outputFormat);
} catch (e) {
debug("Failed reading converted file");
return "";
}
return result;
};
var convert = function (obj, cb) {
getX2T(function (x2t) {
// Fonts
fetchFonts(x2t, obj, function () {
var o = obj.outputFormat;
if (o !== 'pdf') {
// Add intermediary conversion to Microsoft Office format if needed
// (bin to pdf is allowed)
[
// Import from Open Document
{source: '.ods', format: 'xlsx'},
{source: '.odt', format: 'docx'},
{source: '.odp', format: 'pptx'},
// Export to non Microsoft Office
{source: '.bin', type: 'sheet', format: 'xlsx'},
{source: '.bin', type: 'doc', format: 'docx'},
{source: '.bin', type: 'presentation', format: 'pptx'},
].forEach(function (_step) {
if (obj.fileName.endsWith(_step.source) && obj.outputFormat !== _step.format &&
(!_step.type || _step.type === obj.type)) {
obj.outputFormat = _step.format;
obj.data = x2tConvertDataInternal(x2t, obj);
obj.fileName += '.'+_step.format;
}
});
obj.outputFormat = o;
}
var data = x2tConvertDataInternal(x2t, obj);
// Convert to bin -- Import
// We need to extract the images
var images;
if (o === 'bin') {
images = [];
var files = x2t.FS.readdir("/working/media/");
files.forEach(function (file) {
if (file !== "." && file !== "..") {
var fileData = x2t.FS.readFile("/working/media/" + file, {
encoding : "binary"
});
images.push({
name: file,
data: fileData
});
}
});
}
cb({
data: data,
images: images
});
});
});
};
return {
convert: convert
};
};
return X2T;
});

@ -8,7 +8,6 @@ define([
'/common/hyperscript.js', '/common/hyperscript.js',
'/customize/messages.js', '/customize/messages.js',
'/common/common-interface.js', '/common/common-interface.js',
'/common/common-util.js',
'/bower_components/file-saver/FileSaver.min.js', '/bower_components/file-saver/FileSaver.min.js',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
@ -23,8 +22,7 @@ define([
SFCommon, SFCommon,
h, h,
Messages, Messages,
UI, UI
Util
) )
{ {
var APP = {}; var APP = {};
@ -32,126 +30,21 @@ define([
var common; var common;
var sFrameChan; var sFrameChan;
var debug = console.debug;
var x2tReady = Util.mkEvent(true);
var x2tInitialized = false;
var x2tInit = function(x2t) {
debug("x2t mount");
// x2t.FS.mount(x2t.MEMFS, {} , '/');
x2t.FS.mkdir('/working');
x2t.FS.mkdir('/working/media');
x2t.FS.mkdir('/working/fonts');
x2tInitialized = true;
x2tReady.fire();
//fetchFonts(x2t);
debug("x2t mount done");
};
var getX2t = function (cb) {
require(['/common/onlyoffice/x2t/x2t.js'], function() { // FIXME why does this fail without an access-control-allow-origin header?
var x2t = window.Module;
x2t.run();
if (x2tInitialized) {
debug("x2t runtime already initialized");
return void x2tReady.reg(function () {
cb(x2t);
});
}
x2t.onRuntimeInitialized = function() {
debug("x2t in runtime initialized");
// Init x2t js module
x2tInit(x2t);
x2tReady.reg(function () {
cb(x2t);
});
};
});
};
/*
Converting Data
This function converts a data in a specific format to the outputformat
The filename extension needs to represent the input format
Example: fileName=cryptpad.bin outputFormat=xlsx
*/
var getFormatId = function (ext) {
// Sheets
if (ext === 'xlsx') { return 257; }
if (ext === 'xls') { return 258; }
if (ext === 'ods') { return 259; }
if (ext === 'csv') { return 260; }
if (ext === 'pdf') { return 513; }
// Docs
if (ext === 'docx') { return 65; }
if (ext === 'doc') { return 66; }
if (ext === 'odt') { return 67; }
if (ext === 'txt') { return 69; }
if (ext === 'html') { return 70; }
// Slides
if (ext === 'pptx') { return 129; }
if (ext === 'ppt') { return 130; }
if (ext === 'odp') { return 131; }
return;
};
var getFromId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatFrom>'+id+'</m_nFormatFrom>';
};
var getToId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return '<m_nFormatTo>'+id+'</m_nFormatTo>';
};
var x2tConvertDataInternal = function(x2t, data, fileName, outputFormat) {
debug("Converting Data for " + fileName + " to " + outputFormat);
var inputFormat = fileName.split('.').pop();
x2t.FS.writeFile('/working/' + fileName, data);
var params = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<TaskQueueDataConvert xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
+ "<m_sFileFrom>/working/" + fileName + "</m_sFileFrom>"
+ "<m_sFileTo>/working/" + fileName + "." + outputFormat + "</m_sFileTo>"
+ getFromId(inputFormat)
+ getToId(outputFormat)
+ "<m_bIsNoBase64>false</m_bIsNoBase64>"
+ "</TaskQueueDataConvert>";
// writing params file to mounted working disk (in memory)
x2t.FS.writeFile('/working/params.xml', params);
// running conversion
x2t.ccall("runX2T", ["number"], ["string"], ["/working/params.xml"]);
// reading output file from working disk (in memory)
var result;
try {
result = x2t.FS.readFile('/working/' + fileName + "." + outputFormat);
} catch (e) {
console.error(e, x2t.FS);
debug("Failed reading converted file");
UI.warn(Messages.error);
return "";
}
return result;
};
var x2tConverter = function (typeSrc, typeTarget) { var x2tConverter = function (typeSrc, typeTarget) {
return function (data, name, cb) { return function (data, name, cb) {
getX2t(function (x2t) { var sframeChan = common.getSframeChannel();
if (typeSrc === 'ods') { sframeChan.query('Q_OO_CONVERT', {
data = x2tConvertDataInternal(x2t, data, name, 'xlsx'); data: data,
name += '.xlsx'; fileName: name,
} outputFormat: typeTarget,
if (typeSrc === 'odt') { }, function (err, obj) {
data = x2tConvertDataInternal(x2t, data, name, 'docx'); if (err || !obj || !obj.data) {
name += '.docx'; UI.warn(Messages.error);
} cb();
if (typeSrc === 'odp') {
data = x2tConvertDataInternal(x2t, data, name, 'pptx');
name += '.pptx';
} }
cb(x2tConvertDataInternal(x2t, data, name, typeTarget)); cb(obj.data, obj.images);
}, {
raw: true
}); });
}; };
}; };

@ -17,11 +17,26 @@ define([
category = window.location.hash.slice(1); category = window.location.hash.slice(1);
window.location.hash = ''; window.location.hash = '';
} }
var addRpc = function (sframeChan) {
// X2T
var x2t;
var onConvert = function (obj, cb) {
x2t.convert(obj, cb);
};
sframeChan.on('Q_OO_CONVERT', function (obj, cb) {
if (x2t) { return void onConvert(obj, cb); }
require(['/common/outer/x2t.js'], function (X2T) {
x2t = X2T.start();
onConvert(obj, cb);
});
});
};
var addData = function (obj) { var addData = function (obj) {
if (category) { obj.category = category; } if (category) { obj.category = category; }
}; };
SFCommonO.start({ SFCommonO.start({
noRealtime: true, noRealtime: true,
addRpc: addRpc,
addData: addData addData: addData
}); });
}); });

Loading…
Cancel
Save