import storage from './storage';
import {SVGRenderer} from 'scratch-svg-renderer';

// Contains 'font-family', but doesn't only contain 'font-family="none"'
const HAS_FONT_REGEXP = 'font-family(?!="none")';

const getCostumeUrl = (function () {
    let cachedAssetId;
    let cachedUrl;

    return function (asset) {

        if (cachedAssetId === asset.assetId) {
            return cachedUrl;
        }

        cachedAssetId = asset.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) {
            const svgString = asset.decodeText();
            if (svgString.match(HAS_FONT_REGEXP)) {
                const svgRenderer = new SVGRenderer();
                svgRenderer.loadString(svgString);
                const svgText = svgRenderer.toString(true /* shouldInjectFonts */);
                cachedUrl = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
            } else {
                cachedUrl = asset.encodeDataURI();
            }
        } else {
            cachedUrl = asset.encodeDataURI();
        }

        return cachedUrl;
    };
}());

export {
    getCostumeUrl as default,
    HAS_FONT_REGEXP
};

import storage from './storage';
import {inlineSvgFonts} from 'scratch-svg-renderer';

// Contains 'font-family', but doesn't only contain 'font-family="none"'
const HAS_FONT_REGEXP = 'font-family(?!="none")';

const getCostumeUrl = (function () {
    let cachedAssetId;
    let cachedUrl;

    return function (asset) {

        if (cachedAssetId === asset.assetId) {
            return cachedUrl;
        }

        cachedAssetId = asset.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) {
            const svgString = asset.decodeText();
            if (svgString.match(HAS_FONT_REGEXP)) {
                const svgText = inlineSvgFonts(svgString);
                cachedUrl = `data:image/svg+xml;utf8,${encodeURIComponent(svgText)}`;
            } else {
                cachedUrl = asset.encodeDataURI();
            }
        } else {
            cachedUrl = asset.encodeDataURI();
        }

        return cachedUrl;
    };
}());

export {
    getCostumeUrl as default,
    HAS_FONT_REGEXP
};

Use fontInliner instead of entire SVGRenderer for showing costume tiles.
Use fontInliner instead of entire SVGRenderer for showing costume tiles.

The fontInliner from the scratch-svg-renderer was changed recently to work entirely on strings, so we can use that instead of parsing/loading/possibly drawing/stringifying the entire SVG. 

This does not address the size-1 cache issue where the cache is invalidated any time there is more than 1 sprite. But that can be handled later.

Using the 4x CPU slowdown in chrome dev tools, on a simple costume that just has a single text element the getCostumeUrl time goes from 10ms to 1ms, very important for updating in a timely way.
