You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cryptpad/www/common/outer/x2t.js

275 lines
11 KiB
JavaScript

define([
'/api/config',
'/bower_components/nthen/index.js',
'/common/common-util.js',
], function (ApiConfig, 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 = ApiConfig.httpSafeOrigin + '/common/onlyoffice/'+CURRENT_VERSION+'/fonts/';
var ver = '?' + ApiConfig.requireConf.urlArgs;
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 + ver, 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');
x2t.FS.mkdir('/working/themes');
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) {
if (/\.bin$/.test(_mediaFileName)) { return; }
var mediasSources = obj.mediasSources || {};
var mediasData = obj.mediasData || {};
var mediaData = mediasData[_mediaFileName];
var mediaFileName;
if (mediaData) { // Theme image
var path = _mediaFileName.split('/');
mediaFileName = path.pop();
var theme = path[path.indexOf('themes') + 1];
try {
x2t.FS.mkdir('/working/themes/'+theme);
x2t.FS.mkdir('/working/themes/'+theme+'/media');
} catch (e) {
console.warn(e);
}
x2t.FS.writeFile('/working/themes/'+theme+'/media/' + mediaFileName, new Uint8Array(mediaData.content));
debug("Writing media data " + mediaFileName + " at /working/themes/"+theme+"/media/");
return;
}
// mediaData is undefined, check mediasSources
mediaFileName = _mediaFileName.substring(6);
var mediaSource = mediasSources[mediaFileName];
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_sThemeDir>/working/themes</m_sThemeDir>"
+ "<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);
try {
// running conversion
x2t.ccall("runX2T", ["number"], ["string"], ["/working/params.xml"]);
} catch (e) {
console.error(e);
return "";
}
// 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) {
console.error(obj);
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;
});