diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 0a051250..34c4e1fe 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -193,7 +193,8 @@ TODOS enterNewLinkURL: 'Enter the new hyperlink URL', errorLoadingSVG: 'Error: Unable to load SVG data', URLloadFail: 'Unable to load from URL', - retrieving: 'Retrieving \'%s\' ...' + retrieving: 'Retrieving \'%s\' ...', + popupWindowBlocked: 'Popup window may be blocked by browser' } }; @@ -1086,10 +1087,15 @@ TODOS exportWindowName = data.exportWindowName; if (exportWindowName) { - exportWindow = window.open('', exportWindowName); // A hack to get the window via JSON-able name without opening a new one + exportWindow = window.open(svgedit.utilities.blankPageObjectURL || '', exportWindowName); // A hack to get the window via JSON-able name without opening a new one } - exportWindow.location.href = data.datauri; + if (!exportWindow || exportWindow.closed) { + $.alert(uiStrings.notification.popupWindowBlocked); + return; + } + + exportWindow.location.href = data.bloburl || data.datauri; var done = $.pref('export_notice_done'); if (done !== 'all') { var note = uiStrings.notification.saveFromBrowser.replace('%s', data.type); @@ -3602,6 +3608,7 @@ TODOS svgCanvas.save(saveOpts); }; + var loadingURL; var clickExport = function() { $.select('Select an image type for export: ', [ // See http://kangax.github.io/jstests/toDataUrl_mime_type_test/ for a useful list of MIME types and browser support @@ -3620,10 +3627,20 @@ TODOS editor.exportWindowCt++; } exportWindowName = curConfig.canvasName + editor.exportWindowCt; - exportWindow = window.open( - 'data:text/html;charset=utf-8,' + encodeURIComponent('' + str + '

' + str + '

'), - exportWindowName - ); + var popHTML, popURL; + if (loadingURL) { + popURL = loadingURL; + } else { + popHTML = '' + str + '

' + str + '

'; + if (typeof URL && URL.createObjectURL) { + var blob = new Blob([popHTML], {type:'text/html'}); + popURL = URL.createObjectURL(blob); + } else { + popURL = 'data:text/html;base64;charset=utf-8,' + svgedit.utilities.encode64(popHTML); + } + loadingURL = popURL; + } + exportWindow = window.open(popURL, exportWindowName); } if (imgType === 'PDF') { if (!customExportPDF) { diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index d0b4795d..17f8e594 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -4063,8 +4063,15 @@ this.rasterExport = function(imgType, quality, exportWindowName) { canvg(c, str, {renderCallback: function() { var dataURLType = (type === 'ICO' ? 'BMP' : type).toLowerCase(); var datauri = quality ? c.toDataURL('image/' + dataURLType, quality) : c.toDataURL('image/' + dataURLType); - - call('exported', {datauri: datauri, svg: str, issues: issues, type: imgType, mimeType: mimeType, quality: quality, exportWindowName: exportWindowName}); + if (c.toBlob) { + c.toBlob(function (blob) { + var bloburl = svgedit.utilities.createObjectURL(blob); + call('exported', {datauri: datauri, bloburl: bloburl, svg: str, issues: issues, type: imgType, mimeType: mimeType, quality: quality, exportWindowName: exportWindowName}); + }, mimeType, quality); + return; + } + var bloburl = svgedit.utilities.dataURLToObjectURL(datauri); + call('exported', {datauri: datauri, bloburl: bloburl, svg: str, issues: issues, type: imgType, mimeType: mimeType, quality: quality, exportWindowName: exportWindowName}); }}); })(); }; diff --git a/editor/svgutils.js b/editor/svgutils.js index e5eb7d3b..a8453147 100644 --- a/editor/svgutils.js +++ b/editor/svgutils.js @@ -170,6 +170,47 @@ svgedit.utilities.encodeUTF8 = function (argString) { return unescape(encodeURIComponent(argString)); }; +/** + * convert dataURL to object URL + * @param {string} dataurl + * @return {string} object URL or empty string + */ +svgedit.utilities.dataURLToObjectURL = function (dataurl) { + if (typeof Uint8Array == 'undefined' || typeof Blob == 'undefined' || typeof URL == 'undefined' || !URL.createObjectURL) { + return ''; + } + var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], + bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + var blob = new Blob([u8arr], {type:mime}); + return URL.createObjectURL(blob); +}; + +/** + * get object URL for a blob object + * @param {Blob} blob A Blob object or File object + * @return {string} object URL or empty string + */ +svgedit.utilities.createObjectURL = function (blob) { + if (!blob || typeof URL == 'undefined' || !URL.createObjectURL) { + return ''; + } + return URL.createObjectURL(blob); +}; + +/** + * @property {string} blankPageObjectURL + */ +svgedit.utilities.blankPageObjectURL = function () { + if (typeof Blob == 'undefined') { + return ''; + } + var blob = new Blob(['SVG-edit '], {type:'text/html'}); + return svgedit.utilities.createObjectURL(blob); +}(); + // Function: svgedit.utilities.convertToXMLReferences // Converts a string to use XML references svgedit.utilities.convertToXMLReferences = function(input) {