diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx index 83b27d4c3252cccd83c1f1567d73d486c4790b5d..39e0419acdd720dec654f37bf9244dfe2014e573 100644 --- a/src/containers/costume-tab.jsx +++ b/src/containers/costume-tab.jsx @@ -13,7 +13,7 @@ import errorBoundaryHOC from '../lib/error-boundary-hoc.jsx'; import DragConstants from '../lib/drag-constants'; import {emptyCostume} from '../lib/empty-assets'; import sharedMessages from '../lib/shared-messages'; -import download from '../lib/download-url'; +import downloadBlob from '../lib/download-blob'; import { closeCameraCapture, @@ -154,7 +154,8 @@ class CostumeTab extends React.Component { } handleExportCostume (costumeIndex) { const item = this.props.vm.editingTarget.sprite.costumes[costumeIndex]; - download(`${item.name}.${item.asset.dataFormat}`, item.asset.encodeDataURI()); + const blob = new Blob([item.asset.data], {type: item.asset.assetType.contentType}); + downloadBlob(`${item.name}.${item.asset.dataFormat}`, blob); } handleNewCostume (costume, fromCostumeLibrary) { if (fromCostumeLibrary) { diff --git a/src/containers/monitor.jsx b/src/containers/monitor.jsx index 039fa060d616d2df878f75eff8140fcbdcb51ecb..b35a04bb9c2056b74f276d213ac45fa42a2a343f 100644 --- a/src/containers/monitor.jsx +++ b/src/containers/monitor.jsx @@ -8,7 +8,7 @@ import MonitorComponent, {monitorModes} from '../components/monitor/monitor.jsx' import {addMonitorRect, getInitialPosition, resizeMonitorRect, removeMonitorRect} from '../reducers/monitor-layout'; import {getVariable, setVariableValue} from '../lib/variable-utils'; import importCSV from '../lib/import-csv'; -import download from '../lib/download-url'; +import downloadBlob from '../lib/download-blob'; import {connect} from 'react-redux'; import {Map} from 'immutable'; @@ -156,7 +156,8 @@ class Monitor extends React.Component { const {vm, targetId, id: variableId} = this.props; const variable = getVariable(vm, targetId, variableId); const text = variable.value.join('\r\n'); - download(`${variable.name}.txt`, `data:text/plain;charset=utf-8,${encodeURIComponent(text)}`); + const blob = new Blob([text], {type: 'text/plain;charset=utf-8'}); + downloadBlob(`${variable.name}.txt`, blob); } render () { const monitorProps = monitorAdapter(this.props); diff --git a/src/containers/sb3-downloader.jsx b/src/containers/sb3-downloader.jsx index 47df7bacaebe341abc571d3c9ca7e22e2d024e34..536934a270cfdbaace177fca5e4046a47b38f8ff 100644 --- a/src/containers/sb3-downloader.jsx +++ b/src/containers/sb3-downloader.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import {connect} from 'react-redux'; import {projectTitleInitialState} from '../reducers/project-title'; - +import downloadBlob from '../lib/download-blob'; /** * Project saver component passes a downloadProject function to its child. * It expects this child to be a function with the signature @@ -26,25 +26,11 @@ class SB3Downloader extends React.Component { ]); } downloadProject () { - const downloadLink = document.createElement('a'); - document.body.appendChild(downloadLink); - this.props.saveProjectSb3().then(content => { if (this.props.onSaveFinished) { this.props.onSaveFinished(); } - // Use special ms version if available to get it working on Edge. - if (navigator.msSaveOrOpenBlob) { - navigator.msSaveOrOpenBlob(content, this.props.projectFilename); - return; - } - - const url = window.URL.createObjectURL(content); - downloadLink.href = url; - downloadLink.download = this.props.projectFilename; - downloadLink.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(downloadLink); + downloadBlob(this.props.projectFilename, content); }); } render () { diff --git a/src/containers/sound-tab.jsx b/src/containers/sound-tab.jsx index 40e08dfb737321de558b278c011c4a2e9e980142..3880de2e5349d3df811651a96846cb5c9b06e1a8 100644 --- a/src/containers/sound-tab.jsx +++ b/src/containers/sound-tab.jsx @@ -21,7 +21,7 @@ import soundLibraryContent from '../lib/libraries/sounds.json'; import {handleFileUpload, soundUpload} from '../lib/file-uploader.js'; import errorBoundaryHOC from '../lib/error-boundary-hoc.jsx'; import DragConstants from '../lib/drag-constants'; -import download from '../lib/download-url'; +import downloadBlob from '../lib/download-blob'; import {connect} from 'react-redux'; @@ -90,8 +90,8 @@ class SoundTab extends React.Component { handleExportSound (soundIndex) { const item = this.props.vm.editingTarget.sprite.sounds[soundIndex]; - const soundDataURL = item.asset.encodeDataURI(); - download(`${item.name}.${item.asset.dataFormat}`, soundDataURL); + const blob = new Blob([item.asset.data], {type: item.asset.assetType.contentType}); + downloadBlob(`${item.name}.${item.asset.dataFormat}`, blob); } handleDuplicateSound (soundIndex) { diff --git a/src/containers/target-pane.jsx b/src/containers/target-pane.jsx index 16017423c903b881176569fc9255d13daea02d77..25382b9054c43de3e007be12fae4202c954b8860 100644 --- a/src/containers/target-pane.jsx +++ b/src/containers/target-pane.jsx @@ -21,6 +21,7 @@ import {emptySprite} from '../lib/empty-assets'; import {highlightTarget} from '../reducers/targets'; import {fetchSprite, fetchCode} from '../lib/backpack-api'; import randomizeSpritePosition from '../lib/randomize-sprite-position'; +import downloadBlob from '../lib/download-blob'; class TargetPane extends React.Component { constructor (props) { @@ -94,20 +95,7 @@ class TargetPane extends React.Component { document.body.appendChild(saveLink); this.props.vm.exportSprite(id).then(content => { - const filename = `${spriteName}.sprite3`; - - // Use special ms version if available to get it working on Edge. - if (navigator.msSaveOrOpenBlob) { - navigator.msSaveOrOpenBlob(content, filename); - return; - } - - const url = window.URL.createObjectURL(content); - saveLink.href = url; - saveLink.download = filename; - saveLink.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(saveLink); + downloadBlob(`${spriteName}.sprite3`, content); }); } handleSelectSprite (id) { diff --git a/src/lib/download-blob.js b/src/lib/download-blob.js new file mode 100644 index 0000000000000000000000000000000000000000..13d53538c60107d59ce6be9de143ad5d5b5120e7 --- /dev/null +++ b/src/lib/download-blob.js @@ -0,0 +1,17 @@ +export default (filename, blob) => { + const downloadLink = document.createElement('a'); + document.body.appendChild(downloadLink); + + // Use special ms version if available to get it working on Edge. + if (navigator.msSaveOrOpenBlob) { + navigator.msSaveOrOpenBlob(blob, filename); + return; + } + + const url = window.URL.createObjectURL(blob); + downloadLink.href = url; + downloadLink.download = filename; + downloadLink.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(downloadLink); +}; diff --git a/src/lib/download-url.js b/src/lib/download-url.js deleted file mode 100644 index e01cb1f0890bf103d704c661b0795bce721418bd..0000000000000000000000000000000000000000 --- a/src/lib/download-url.js +++ /dev/null @@ -1,13 +0,0 @@ -export default (filename, url) => { - const pom = document.createElement('a'); - pom.setAttribute('href', url); - pom.setAttribute('download', filename); - - if (document.createEvent) { - const event = document.createEvent('MouseEvents'); - event.initEvent('click', true, true); - pom.dispatchEvent(event); - } else { - pom.click(); - } -};