define([
'/api/config',
'/bower_components/nthen/index.js',
'/common/common-util.js',
], function (ApiConfig, nThen, Util) {
var X2T = {};
var CURRENT_VERSION = X2T.CURRENT_VERSION = 'v5';
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 ''+id+'';
};
var getToId = function (ext) {
var id = getFormatId(ext);
if (!id) { return ''; }
return ''+id+'';
};
// Sanitize file names
var illegalRe = /[\/\?<>\\:\*\|"]/g;
var controlRe = /[\x00-\x1f\x80-\x9f]/g;
var reservedRe = /^\.+$/;
var safeRe = /[&'%!"{}[\]]/g;
var sanitize = function (input) {
if (typeof input !== 'string') { return 'file'; }
var s = input.split('.');
var ext = s.pop() || 'bin';
var name = s.join('');
var replacement = '';
console.error(name);
var sanitized = name
.replace(illegalRe, replacement)
.replace(controlRe, replacement)
.replace(reservedRe, replacement)
.replace(safeRe, replacement);
sanitized = sanitized || 'file';
return sanitized.slice(0, 255) + '.' + ext;
};
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 = "false" +
"/working/fonts/";
// 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 = ""
+ ""
+ "/working/" + fileName + ""
+ "/working/themes"
+ "/working/" + fileName + "." + outputFormat + ""
+ pdfData
+ getFromId(inputFormat)
+ getToId(outputFormat)
+ "false"
+ "";
// 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);
obj.fileName = sanitize(obj.fileName);
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;
});