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

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

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;
});