Skip to content

Instantly share code, notes, and snippets.

@westc
Last active March 27, 2023 18:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save westc/4e6afff13e84b63df07f5c11d7d63a45 to your computer and use it in GitHub Desktop.
Save westc/4e6afff13e84b63df07f5c11d7d63a45 to your computer and use it in GitHub Desktop.
toDataURL() - Turns a string that can represent a text document and returns the corresponding data URL (AKA data URI).
/**
* Turns a string that can represent a text document and returns the
* corresponding data URL (AKA data URI).
* @param {string} text
* The text to turn into a data URL.
* @param {Object} options
* Optional. An object containing the different options to set.
* @param {boolean=} options.base64
* Optional, defaults to the `false`. Indicates if the returned data URL
* should be base64 encoded.
* @param {string=} options.charset
* Optional. Indicates the character set of the content. Examples are
* "US-ASCII", "UTF-8", etc.
* @param {string=} options.type
* Optional, defaults to the empty string. The content type of `text` (eg.
* `"text/html"`).
* @returns {string}
* A data URL which represents `text` as the given `type`.
*/
function toDataURL(text, options) {
let {base64, charset, type} = Object(options);
return ('data:'
+ (type ?? '')
+ ';'
+ (charset ? 'charset=' + charset + ';' : '')
+ (base64 ? 'base64;' : '')
).replace(/;$/, '')
+ ','
+ (base64
// unescape() and encodeURIComponent() used based on this solution:
// https://stackoverflow.com/a/26603875/657132
? window.btoa(unescape(encodeURIComponent(text)))
: encodeURIComponent(text)
);
}
/**
* Turns a string that can represent a text document and returns the
* corresponding data URL (AKA data URI). Leverages `FileReader` and `Blob`
* to ensure validity of data URL's contents.
* @param {string} text
* The text to turn into a data URL.
* @param {Object} options
* Optional. An object containing the different options to set.
* @param {boolean=} options.base64
* Optional, defaults to the `false`. Indicates if the returned data URL
* should be base64 encoded.
* @param {string=} options.charset
* Optional. Indicates the character set of the content. Examples are
* "US-ASCII", "UTF-8", etc.
* @param {string=} options.type
* Optional, defaults to the empty string. The content type of `text` (eg.
* `"text/html"`).
* @returns {Promise<string>}
* A data URL which represents `text` as the given `type`.
*/
function toAsyncDataURL(text, options) {
let {base64, charset, type} = Object(options);
return new Promise(resolve => {
Object.assign(new FileReader(), {
onload({target: {result}}) {
result = /,([^]*$)/.exec(result)[1];
resolve(
('data:'
+ (type ?? '')
+ ';'
+ (charset ? 'charset=' + charset + ';' : '')
+ (base64 ? 'base64;' : '')
).replace(/;$/, '')
+ ','
+ (base64 ? result : encodeURIComponent(decodeURIComponent(escape(atob(result)))))
);
}
}).readAsDataURL(new Blob([text], {type: charset ? ';charset=' + charset : ''}));
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment