diff --git a/package.json b/package.json
index 4baa85c74c810487f5c4dc521caac6b2e9decf3f..24345d73f2332244b9be0678217a636cc0062a04 100644
--- a/package.json
+++ b/package.json
@@ -98,7 +98,7 @@
     "scratch-audio": "0.1.0-prerelease.20180625202813",
     "scratch-blocks": "0.1.0-prerelease.1534979688",
     "scratch-l10n": "3.0.20180823152851",
-    "scratch-paint": "0.2.0-prerelease.20180816205442",
+    "scratch-paint": "0.2.0-prerelease.20180822171824",
     "scratch-render": "0.1.0-prerelease.20180820154012",
     "scratch-storage": "0.5.1",
     "scratch-svg-renderer": "0.2.0-prerelease.20180817005452",
diff --git a/src/containers/controls.jsx b/src/containers/controls.jsx
index 7cc52870fea7dad1e58b168d406019a4a4549162..2869a047a6ba5722762d86f32875419cd14cfb0b 100644
--- a/src/containers/controls.jsx
+++ b/src/containers/controls.jsx
@@ -64,5 +64,7 @@ const mapStateToProps = state => ({
     projectRunning: state.scratchGui.vmStatus.running,
     turbo: state.scratchGui.vmStatus.turbo
 });
+// no-op function to prevent dispatch prop being passed to component
+const mapDispatchToProps = () => ({});
 
-export default connect(mapStateToProps)(Controls);
+export default connect(mapStateToProps, mapDispatchToProps)(Controls);
diff --git a/src/containers/error-boundary.jsx b/src/containers/error-boundary.jsx
index fbb15f3b998d1deb80cb309146c1dfa48d88a593..6485a41b84b7cf227ec4e54e496f2afbe0d88c2f 100644
--- a/src/containers/error-boundary.jsx
+++ b/src/containers/error-boundary.jsx
@@ -78,6 +78,6 @@ const mapStateToProps = state => ({
 });
 
 // no-op function to prevent dispatch prop being passed to component
-const mapDispatchToProps = () => {};
+const mapDispatchToProps = () => ({});
 
 export default connect(mapStateToProps, mapDispatchToProps)(ErrorBoundary);
diff --git a/src/containers/sprite-selector-item.jsx b/src/containers/sprite-selector-item.jsx
index a0197ad6dd9ecfc09e61c5a783878395eef7e509..01e617c8e77385244507977b037c7f31a918a26d 100644
--- a/src/containers/sprite-selector-item.jsx
+++ b/src/containers/sprite-selector-item.jsx
@@ -2,28 +2,24 @@ import bindAll from 'lodash.bindall';
 import PropTypes from 'prop-types';
 import React from 'react';
 import {connect} from 'react-redux';
-import {defineMessages, injectIntl, intlShape} from 'react-intl';
 
 import {setHoveredSprite} from '../reducers/hovered-target';
 import {updateAssetDrag} from '../reducers/asset-drag';
 import {getEventXY} from '../lib/touch-utils';
+import VM from 'scratch-vm';
+import {SVGRenderer} from 'scratch-svg-renderer';
 
 import SpriteSelectorItemComponent from '../components/sprite-selector-item/sprite-selector-item.jsx';
 
 const dragThreshold = 3; // Same as the block drag threshold
-
-const messages = defineMessages({
-    deleteSpriteConfirmation: {
-        defaultMessage: 'Are you sure you want to delete this?',
-        description: 'Confirmation for deleting sprites',
-        id: 'gui.spriteSelectorItem.deleteSpriteConfirmation'
-    }
-});
+// Contains 'font-family', but doesn't only contain 'font-family="none"'
+const HAS_FONT_REGEXP = 'font-family(?!="none")';
 
 class SpriteSelectorItem extends React.Component {
     constructor (props) {
         super(props);
         bindAll(this, [
+            'getCostumeUrl',
             'handleClick',
             'handleDelete',
             'handleDuplicate',
@@ -34,6 +30,34 @@ class SpriteSelectorItem extends React.Component {
             'handleMouseMove',
             'handleMouseUp'
         ]);
+        this.svgRenderer = new SVGRenderer();
+        // Asset ID of the SVG currently in SVGRenderer
+        this.svgRendererAssetId = null;
+    }
+    getCostumeUrl () {
+        if (this.props.costumeURL) return this.props.costumeURL;
+        if (!this.props.assetId) return null;
+
+        const storage = this.props.vm.runtime.storage;
+        const asset = storage.get(this.props.assetId);
+        // If the SVG refers to fonts, they must be inlined in order to display correctly in the img tag.
+        // Avoid parsing the SVG when possible, since it's expensive.
+        if (asset.assetType === storage.AssetType.ImageVector) {
+            // If the asset ID has not changed, no need to re-parse
+            if (this.svgRendererAssetId === this.props.assetId) {
+                return this.cachedUrl;
+            }
+
+            const svgString = this.props.vm.runtime.storage.get(this.props.assetId).decodeText();
+            if (svgString.match(HAS_FONT_REGEXP)) {
+                this.svgRendererAssetId = this.props.assetId;
+                this.svgRenderer.loadString(svgString);
+                const svgText = this.svgRenderer.toString(true /* shouldInjectFonts */);
+                this.cachedUrl = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
+                return this.cachedUrl;
+            }
+        }
+        return this.props.vm.runtime.storage.get(this.props.assetId).encodeDataURI();
     }
     handleMouseUp () {
         this.initialOffset = null;
@@ -58,7 +82,7 @@ class SpriteSelectorItem extends React.Component {
         const dy = currentOffset.y - this.initialOffset.y;
         if (Math.sqrt((dx * dx) + (dy * dy)) > dragThreshold) {
             this.props.onDrag({
-                img: this.props.costumeURL,
+                img: this.getCostumeUrl(),
                 currentOffset: currentOffset,
                 dragging: true,
                 dragType: this.props.dragType,
@@ -84,10 +108,7 @@ class SpriteSelectorItem extends React.Component {
     }
     handleDelete (e) {
         e.stopPropagation(); // To prevent from bubbling back to handleClick
-        // eslint-disable-next-line no-alert
-        if (window.confirm(this.props.intl.formatMessage(messages.deleteSpriteConfirmation))) {
-            this.props.onDeleteButtonClick(this.props.id);
-        }
+        this.props.onDeleteButtonClick(this.props.id);
     }
     handleDuplicate (e) {
         e.stopPropagation(); // To prevent from bubbling back to handleClick
@@ -115,11 +136,14 @@ class SpriteSelectorItem extends React.Component {
             onExportButtonClick,
             dragPayload,
             receivedBlocks,
+            costumeURL,
+            vm,
             /* eslint-enable no-unused-vars */
             ...props
         } = this.props;
         return (
             <SpriteSelectorItemComponent
+                costumeURL={this.getCostumeUrl()}
                 onClick={this.handleClick}
                 onDeleteButtonClick={onDeleteButtonClick ? this.handleDelete : null}
                 onDuplicateButtonClick={onDuplicateButtonClick ? this.handleDuplicate : null}
@@ -144,7 +168,6 @@ SpriteSelectorItem.propTypes = {
     dragType: PropTypes.string,
     id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
     index: PropTypes.number,
-    intl: intlShape.isRequired,
     name: PropTypes.string,
     onClick: PropTypes.func,
     onDeleteButtonClick: PropTypes.func,
@@ -152,14 +175,15 @@ SpriteSelectorItem.propTypes = {
     onDuplicateButtonClick: PropTypes.func,
     onExportButtonClick: PropTypes.func,
     receivedBlocks: PropTypes.bool.isRequired,
-    selected: PropTypes.bool
+    selected: PropTypes.bool,
+    vm: PropTypes.instanceOf(VM).isRequired
 };
 
-const mapStateToProps = (state, {assetId, costumeURL, id}) => ({
-    costumeURL: costumeURL || (assetId && state.scratchGui.vm.runtime.storage.get(assetId).encodeDataURI()),
+const mapStateToProps = (state, {id}) => ({
     dragging: state.scratchGui.assetDrag.dragging,
     receivedBlocks: state.scratchGui.hoveredTarget.receivedBlocks &&
-            state.scratchGui.hoveredTarget.sprite === id
+            state.scratchGui.hoveredTarget.sprite === id,
+    vm: state.scratchGui.vm
 });
 const mapDispatchToProps = dispatch => ({
     dispatchSetHoveredSprite: spriteId => {
@@ -168,8 +192,12 @@ const mapDispatchToProps = dispatch => ({
     onDrag: data => dispatch(updateAssetDrag(data))
 });
 
-
-export default connect(
+const ConnectedComponent = connect(
     mapStateToProps,
     mapDispatchToProps
-)(injectIntl(SpriteSelectorItem));
+)(SpriteSelectorItem);
+
+export {
+    ConnectedComponent as default,
+    HAS_FONT_REGEXP // Exposed for testing
+};
diff --git a/src/lib/vm-listener-hoc.jsx b/src/lib/vm-listener-hoc.jsx
index b2256b82a4ace77d8d2bec3a426bb02852cd3464..67e70f90019e90b92c262fdef5067c12c9c927ff 100644
--- a/src/lib/vm-listener-hoc.jsx
+++ b/src/lib/vm-listener-hoc.jsx
@@ -89,6 +89,10 @@ const vmListenerHOC = function (WrappedComponent) {
                 onKeyUp,
                 onMonitorsUpdate,
                 onTargetsUpdate,
+                onProjectRunStart,
+                onProjectRunStop,
+                onTurboModeOff,
+                onTurboModeOn,
                 /* eslint-enable no-unused-vars */
                 ...props
             } = this.props;
diff --git a/test/integration/sounds.test.js b/test/integration/sounds.test.js
index 7c306a5eee2c9c05c2d16d1c9ed8a1a489f5370c..ca1a3d275d8271e63af5068659429d4b4a4cee7e 100644
--- a/test/integration/sounds.test.js
+++ b/test/integration/sounds.test.js
@@ -33,8 +33,6 @@ describe('Working with sounds', () => {
         // Delete the sound
         await rightClickText('Meow', scope.soundsTab);
         await clickText('delete', scope.soundsTab);
-        await driver.switchTo().alert()
-            .accept();
 
         // Add it back
         await clickXpath('//button[@aria-label="Choose a Sound"]');
diff --git a/test/integration/sprites.test.js b/test/integration/sprites.test.js
index 41f2eec3ab4220e83fc08f8936c35328367f3da4..5b99efcb62e0496312d31f15e8746b260ad204a1 100644
--- a/test/integration/sprites.test.js
+++ b/test/integration/sprites.test.js
@@ -55,8 +55,6 @@ describe('Working with sprites', () => {
         await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
         await rightClickText('Sprite1', scope.spriteTile);
         await clickText('delete', scope.spriteTile);
-        await driver.switchTo().alert()
-            .accept();
         // Confirm that the stage has been switched to
         await findByText('Stage selected: no motion blocks');
         const logs = await getLogs();
diff --git a/test/unit/containers/sprite-selector-item.test.jsx b/test/unit/containers/sprite-selector-item.test.jsx
index 85032603d4b3a1712db3fb431a96d109dc40d7d7..25200a1fb5f8376bd7ade0d9b13ff98eaf990885 100644
--- a/test/unit/containers/sprite-selector-item.test.jsx
+++ b/test/unit/containers/sprite-selector-item.test.jsx
@@ -4,6 +4,7 @@ import configureStore from 'redux-mock-store';
 import {Provider} from 'react-redux';
 
 import SpriteSelectorItem from '../../../src/containers/sprite-selector-item';
+import {HAS_FONT_REGEXP} from '../../../src/containers/sprite-selector-item';
 import CloseButton from '../../../src/components/close-button/close-button';
 
 describe('SpriteSelectorItem Container', () => {
@@ -48,22 +49,19 @@ describe('SpriteSelectorItem Container', () => {
         onDeleteButtonClick = jest.fn();
         dispatchSetHoveredSprite = jest.fn();
         selected = true;
-        // Mock window.confirm() which is called when the close button is clicked.
-        global.confirm = jest.fn(() => true);
     });
 
-    test('should confirm if the user really wants to delete the sprite', () => {
+    test('should delete the sprite', () => {
         const wrapper = mountWithIntl(getContainer());
         wrapper.find(CloseButton).simulate('click');
-        expect(global.confirm).toHaveBeenCalled();
         expect(onDeleteButtonClick).toHaveBeenCalledWith(1337);
     });
 
-    test('should not delete the sprite if the user cancels', () => {
-        global.confirm = jest.fn(() => false);
-        const wrapper = mountWithIntl(getContainer());
-        wrapper.find(CloseButton).simulate('click');
-        expect(global.confirm).toHaveBeenCalled();
-        expect(onDeleteButtonClick).not.toHaveBeenCalled();
+    test('Has font regexp works', () => {
+        expect('font-family="Sans Serif"'.match(HAS_FONT_REGEXP)).toBeTruthy();
+        expect('font-family="none" font-family="Sans Serif"'.match(HAS_FONT_REGEXP)).toBeTruthy();
+        expect('font-family = "Sans Serif"'.match(HAS_FONT_REGEXP)).toBeTruthy();
+
+        expect('font-family="none"'.match(HAS_FONT_REGEXP)).toBeFalsy();
     });
 });