forked from hero/www_hero
56 lines
1.6 KiB
JavaScript
56 lines
1.6 KiB
JavaScript
|
var shorterNames = require('./shorter-css-color-names');
|
||
|
var REGEX = {
|
||
|
whitespace: /\s+/g,
|
||
|
urlHexPairs: /%[\dA-F]{2}/g,
|
||
|
quotes: /"/g,
|
||
|
}
|
||
|
|
||
|
function collapseWhitespace(str) {
|
||
|
return str.trim().replace(REGEX.whitespace, ' ');
|
||
|
}
|
||
|
|
||
|
function dataURIPayload(string) {
|
||
|
return encodeURIComponent(string)
|
||
|
.replace(REGEX.urlHexPairs, specialHexEncode);
|
||
|
}
|
||
|
|
||
|
// `#` gets converted to `%23`, so quite a few CSS named colors are shorter than
|
||
|
// their equivalent URL-encoded hex codes.
|
||
|
function colorCodeToShorterNames(string) {
|
||
|
Object.keys(shorterNames).forEach(function(key) {
|
||
|
if (shorterNames[key].test(string)) {
|
||
|
string = string.replace(shorterNames[key], key);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return string;
|
||
|
}
|
||
|
|
||
|
function specialHexEncode(match) {
|
||
|
switch (match) { // Browsers tolerate these characters, and they're frequent
|
||
|
case '%20': return ' ';
|
||
|
case '%3D': return '=';
|
||
|
case '%3A': return ':';
|
||
|
case '%2F': return '/';
|
||
|
default: return match.toLowerCase(); // compresses better
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function svgToTinyDataUri(svgString) {
|
||
|
if (typeof svgString !== 'string') {
|
||
|
throw new TypeError('Expected a string, but received ' + typeof svgString);
|
||
|
}
|
||
|
// Strip the Byte-Order Mark if the SVG has one
|
||
|
if (svgString.charCodeAt(0) === 0xfeff) { svgString = svgString.slice(1) }
|
||
|
|
||
|
var body = colorCodeToShorterNames(collapseWhitespace(svgString))
|
||
|
.replace(REGEX.quotes, "'");
|
||
|
return 'data:image/svg+xml,' + dataURIPayload(body);
|
||
|
}
|
||
|
|
||
|
svgToTinyDataUri.toSrcset = function toSrcset(svgString) {
|
||
|
return svgToTinyDataUri(svgString).replace(/ /g, '%20');
|
||
|
}
|
||
|
|
||
|
module.exports = svgToTinyDataUri;
|