From d547c90168283da78b418c5b41c24ab8e17c7b96 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 16 Aug 2021 17:44:13 +0200 Subject: [PATCH] Fix SharedArrayBuffer cross-origin issues for X2T --- www/common/onlyoffice/inner.js | 327 ++++++++------------------------- www/common/onlyoffice/main.js | 16 ++ www/common/outer/x2t.js | 243 ++++++++++++++++++++++++ www/convert/inner.js | 133 ++------------ www/convert/main.js | 15 ++ 5 files changed, 360 insertions(+), 374 deletions(-) create mode 100644 www/common/outer/x2t.js diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 2afef4978..2e4b8a43e 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -20,6 +20,7 @@ define([ '/common/onlyoffice/oodoc_base.js', '/common/onlyoffice/ooslide_base.js', '/common/outer/worker-channel.js', + '/common/outer/x2t.js', '/bower_components/file-saver/FileSaver.min.js', @@ -47,7 +48,8 @@ define([ EmptyCell, EmptyDoc, EmptySlide, - Channel) + Channel, + X2T) { var saveAs = window.saveAs; var Nacl = window.nacl; @@ -60,7 +62,7 @@ define([ var DISPLAY_RESTORE_BUTTON = false; var NEW_VERSION = 4; var PENDING_TIMEOUT = 30000; - var CURRENT_VERSION = 'v4'; + var CURRENT_VERSION = X2T.CURRENT_VERSION; //var READONLY_REFRESH_TO = 15000; var debug = function (x, type) { @@ -1699,239 +1701,81 @@ define([ makeChannel(); }; - var x2tReady = Util.mkEvent(true); - var fetchFonts = function (x2t) { - var path = '/common/onlyoffice/'+CURRENT_VERSION+'/fonts/'; + var x2tConvertData = function (data, fileName, format, cb) { + var sframeChan = common.getSframeChannel(); var e = getEditor(); var fonts = e.FontLoader.fontInfos; - var files = e.FontLoader.fontFiles; - 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 () { - x2tReady.fire(); + var files = e.FontLoader.fontFiles.map(function (f) { + return { 'Id': f.Id, }; }); - }; - - 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; - fetchFonts(x2t); - 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); - }); - }; - }); - }; - - - /* - 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 ''+id+''; - }; - var getToId = function (ext) { - var id = getFormatId(ext); - if (!id) { return ''; } - return ''+id+''; - }; - 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 = "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(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); + var type = common.getMetadataMgr().getPrivateData().ooType; + sframeChan.query('Q_OO_CONVERT', { + data: data, + type: type, + fileName: fileName, + outputFormat: format, + images: window.frames[0].AscCommon.g_oDocumentUrls.urls || {}, + fonts: fonts, + fonts_files: files, + mediasSources: getMediasSources(), + mediasData: mediasData + }, function (err, obj) { + if (err || !obj || !obj.data) { + UI.warn(Messages.error); + cb(); } + cb(obj.data, obj.images); + }, { + raw: true }); - - - var inputFormat = fileName.split('.').pop(); - - var params = "" - + "" - + "/working/" + fileName + "" - + "/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); - // 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) { - getX2T(function (x2t) { - //var e = getEditor(); - //var d = e.asc_nativePrint(undefined, undefined, 0x100 + opts.printType).ImData; - var bin = getContent(); - var xlsData = x2tConvertDataInternal(x2t, { - buffer: obj.data, - bin: bin - }, 'output.bin', 'pdf'); - if (xlsData) { - var md = common.getMetadataMgr().getMetadataLazy(); - var type = common.getMetadataMgr().getPrivateData().ooType; - var title = md.title || md.defaultTitle || type; - var blob = new Blob([xlsData], {type: "application/pdf"}); - //var url = URL.createObjectURL(blob, { type: "application/pdf" }); - 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 bin = getContent(); + x2tConvertData({ + buffer: obj.data, + bin: bin + }, 'output.bin', 'pdf', function (xlsData) { + if (!xlsData) { return; } + var md = common.getMetadataMgr().getMetadataLazy(); + var type = common.getMetadataMgr().getPrivateData().ooType; + var title = md.title || md.defaultTitle || type; + var blob = new Blob([xlsData], {type: "application/pdf"}); + saveAs(blob, title+'.pdf'); + cb({ + "type":"save", + "status":"ok", + }); }); }; - var x2tSaveAndConvertDataInternal = function(x2t, data, filename, extension, finalFilename) { + var x2tSaveAndConvertData = function(data, filename, extension, finalFilename) { var type = common.getMetadataMgr().getPrivateData().ooType; - var xlsData; // PDF if (type === "sheet" && extension === "pdf") { var e = getEditor(); var d = e.asc_nativePrint(undefined, undefined, 0x101).ImData; - xlsData = x2tConvertDataInternal(x2t, { + x2tConvertData({ buffer: d.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) { - var _blob = new Blob([xlsData], {type: "application/bin;charset=utf-8"}); + var blob = new Blob([xlsData], {type: "application/bin;charset=utf-8"}); UI.removeModals(); - saveAs(_blob, finalFilename); + saveAs(blob, finalFilename); + return; } - return; - } - 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); + UI.warn(Messages.error); }); }; @@ -2004,32 +1848,29 @@ define([ $select.find('button').addClass('btn'); }; - var x2tImportImagesInternal = function(x2t, images, i, callback) { + var x2tImportImagesInternal = function(images, i, callback) { if (i >= images.length) { callback(); } else { debug("Import image " + i); var handleFileData = { - name: images[i], + name: images[i].name, mediasSources: getMediasSources(), callback: function() { debug("next image"); - x2tImportImagesInternal(x2t, images, i+1, callback); + x2tImportImagesInternal(images, i+1, callback); }, }; - var filePath = "/working/media/" + images[i]; - debug("Import filename " + filePath); - var fileData = x2t.FS.readFile("/working/media/" + images[i], { encoding : "binary" }); - debug("Importing data"); + var fileData = images[i].data; debug("Buffer"); debug(fileData.buffer); var blob = new Blob([fileData.buffer], {type: 'image/png'}); - blob.name = images[i]; + blob.name = images[i].name; APP.FMImages.handleFile(blob, handleFileData); } }; - var x2tImportImages = function (x2t, callback) { + var x2tImportImages = function (images, callback) { if (!APP.FMImages) { var fmConfigImages = { noHandlers: true, @@ -2055,14 +1896,8 @@ define([ // Import Images debug("Import Images"); - var files = x2t.FS.readdir("/working/media/"); - var images = []; - files.forEach(function (file) { - if (file !== "." && file !== "..") { - images.push(file); - } - }); - x2tImportImagesInternal(x2t, images, 0, function() { + debug(images); + x2tImportImagesInternal(images, 0, function() { debug("Sync media sources elements"); debug(getMediasSources()); APP.onLocal(); @@ -2072,26 +1907,12 @@ define([ }; - var x2tConvertData = function (x2t, data, filename, extension, callback) { - var convertedContent; - // Convert from ODF format: - // first convert to Office format then to the selected extension - if (filename.endsWith(".ods")) { - 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); + var x2tImportData = function (data, filename, extension, callback) { + x2tConvertData(new Uint8Array(data), filename, extension, function (binData, images) { + if (!binData) { return void UI.warn(Messages.error); } + x2tImportImages(images, function() { + callback(binData); + }); }); }; @@ -2145,10 +1966,8 @@ define([ ]); UI.openCustomModal(UI.dialog.customModal(div, {buttons: []})); setTimeout(function () { - getX2T(function (x2t) { - x2tConvertData(x2t, new Uint8Array(content), filename.name, "bin", function(c) { - importFile(c); - }); + x2tImportData(new Uint8Array(content), filename.name, "bin", function(c) { + importFile(c); }); }, 100); }; diff --git a/www/common/onlyoffice/main.js b/www/common/onlyoffice/main.js index b7626a589..8b79474ae 100644 --- a/www/common/onlyoffice/main.js +++ b/www/common/onlyoffice/main.js @@ -143,6 +143,22 @@ define([ } 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({ hash: hash, diff --git a/www/common/outer/x2t.js b/www/common/outer/x2t.js new file mode 100644 index 000000000..85b84c0ae --- /dev/null +++ b/www/common/outer/x2t.js @@ -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 ''+id+''; + }; + var getToId = function (ext) { + var id = getFormatId(ext); + if (!id) { return ''; } + return ''+id+''; + }; + + 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) { + 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 = "" + + "" + + "/working/" + fileName + "" + + "/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); + // 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; +}); diff --git a/www/convert/inner.js b/www/convert/inner.js index ba9870ccf..a3b244a8a 100644 --- a/www/convert/inner.js +++ b/www/convert/inner.js @@ -8,7 +8,6 @@ define([ '/common/hyperscript.js', '/customize/messages.js', '/common/common-interface.js', - '/common/common-util.js', '/bower_components/file-saver/FileSaver.min.js', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', @@ -23,8 +22,7 @@ define([ SFCommon, h, Messages, - UI, - Util + UI ) { var APP = {}; @@ -32,126 +30,21 @@ define([ var common; 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 ''+id+''; - }; - var getToId = function (ext) { - var id = getFormatId(ext); - if (!id) { return ''; } - return ''+id+''; - }; - 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 = "" - + "" - + "/working/" + fileName + "" - + "/working/" + fileName + "." + outputFormat + "" - + getFromId(inputFormat) - + getToId(outputFormat) - + "false" - + ""; - // 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) { return function (data, name, cb) { - getX2t(function (x2t) { - if (typeSrc === 'ods') { - data = x2tConvertDataInternal(x2t, data, name, 'xlsx'); - name += '.xlsx'; - } - if (typeSrc === 'odt') { - data = x2tConvertDataInternal(x2t, data, name, 'docx'); - name += '.docx'; - } - if (typeSrc === 'odp') { - data = x2tConvertDataInternal(x2t, data, name, 'pptx'); - name += '.pptx'; + var sframeChan = common.getSframeChannel(); + sframeChan.query('Q_OO_CONVERT', { + data: data, + fileName: name, + outputFormat: typeTarget, + }, function (err, obj) { + if (err || !obj || !obj.data) { + UI.warn(Messages.error); + cb(); } - cb(x2tConvertDataInternal(x2t, data, name, typeTarget)); + cb(obj.data, obj.images); + }, { + raw: true }); }; }; diff --git a/www/convert/main.js b/www/convert/main.js index 236290b13..1bef9f9cd 100644 --- a/www/convert/main.js +++ b/www/convert/main.js @@ -17,11 +17,26 @@ define([ category = window.location.hash.slice(1); 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) { if (category) { obj.category = category; } }; SFCommonO.start({ noRealtime: true, + addRpc: addRpc, addData: addData }); });