147 lines
6.1 KiB
JavaScript
147 lines
6.1 KiB
JavaScript
|
|
|
||
|
|
/**
|
||
|
|
* Export data content to be saved to a local file
|
||
|
|
* @param {string} data Data content converted to a string
|
||
|
|
* @param {string} type The type of
|
||
|
|
* @param {string} filename The filename of the resulting download
|
||
|
|
*/
|
||
|
|
function saveDataToFile(data, type, filename) {
|
||
|
|
const blob = new Blob([data], {type: type});
|
||
|
|
|
||
|
|
// Create an element to trigger the download
|
||
|
|
let a = document.createElement('a');
|
||
|
|
a.href = window.URL.createObjectURL(blob);
|
||
|
|
a.download = filename;
|
||
|
|
|
||
|
|
// Dispatch a click event to the element
|
||
|
|
a.dispatchEvent(new MouseEvent("click", {bubbles: true, cancelable: true, view: window}));
|
||
|
|
setTimeout(() => window.URL.revokeObjectURL(a.href), 100);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Read text data from a user provided File object
|
||
|
|
* @param {File} file A File object
|
||
|
|
* @return {Promise.<String>} A Promise which resolves to the loaded text data
|
||
|
|
*/
|
||
|
|
function readTextFromFile(file) {
|
||
|
|
const reader = new FileReader();
|
||
|
|
return new Promise((resolve, reject) => {
|
||
|
|
reader.onload = ev => {
|
||
|
|
resolve(reader.result);
|
||
|
|
};
|
||
|
|
reader.onerror = ev => {
|
||
|
|
reader.abort();
|
||
|
|
reject();
|
||
|
|
};
|
||
|
|
reader.readAsText(file);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieve a Document by its Universally Unique Identifier (uuid).
|
||
|
|
* @param {string} uuid The uuid of the Document to retrieve.
|
||
|
|
* @param {object} [options] Options to configure how a UUID is resolved.
|
||
|
|
* @param {Document} [options.relative] A Document to resolve relative UUIDs against.
|
||
|
|
* @param {boolean} [options.invalid=false] Allow retrieving an invalid Document.
|
||
|
|
* @returns {Promise<Document|null>} Returns the Document if it could be found, otherwise null.
|
||
|
|
*/
|
||
|
|
async function fromUuid(uuid, options={}) {
|
||
|
|
if ( !uuid ) return null;
|
||
|
|
/** @deprecated since v11 */
|
||
|
|
if ( foundry.utils.getType(options) !== "Object" ) {
|
||
|
|
foundry.utils.logCompatibilityWarning("Passing a relative document as the second parameter to fromUuid is "
|
||
|
|
+ "deprecated. Please pass it within an options object instead.", {since: 11, until: 13});
|
||
|
|
options = {relative: options};
|
||
|
|
}
|
||
|
|
const {relative, invalid=false} = options;
|
||
|
|
let {type, id, primaryId, collection, embedded, doc} = foundry.utils.parseUuid(uuid, {relative});
|
||
|
|
if ( collection instanceof CompendiumCollection ) {
|
||
|
|
if ( type === "Folder" ) return collection.folders.get(id);
|
||
|
|
doc = await collection.getDocument(primaryId ?? id);
|
||
|
|
}
|
||
|
|
else doc = doc ?? collection?.get(primaryId ?? id, {invalid});
|
||
|
|
if ( embedded.length ) doc = _resolveEmbedded(doc, embedded, {invalid});
|
||
|
|
return doc || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Retrieve a Document by its Universally Unique Identifier (uuid) synchronously. If the uuid resolves to a compendium
|
||
|
|
* document, that document's index entry will be returned instead.
|
||
|
|
* @param {string} uuid The uuid of the Document to retrieve.
|
||
|
|
* @param {object} [options] Options to configure how a UUID is resolved.
|
||
|
|
* @param {Document} [options.relative] A Document to resolve relative UUIDs against.
|
||
|
|
* @param {boolean} [options.invalid=false] Allow retrieving an invalid Document.
|
||
|
|
* @param {boolean} [options.strict=true] Throw an error if the UUID cannot be resolved synchronously.
|
||
|
|
* @returns {Document|object|null} The Document or its index entry if it resides in a Compendium, otherwise
|
||
|
|
* null.
|
||
|
|
* @throws If the uuid resolves to a Document that cannot be retrieved synchronously, and the strict option is true.
|
||
|
|
*/
|
||
|
|
function fromUuidSync(uuid, options={}) {
|
||
|
|
if ( !uuid ) return null;
|
||
|
|
/** @deprecated since v11 */
|
||
|
|
if ( foundry.utils.getType(options) !== "Object" ) {
|
||
|
|
foundry.utils.logCompatibilityWarning("Passing a relative document as the second parameter to fromUuidSync is "
|
||
|
|
+ "deprecated. Please pass it within an options object instead.", {since: 11, until: 13});
|
||
|
|
options = {relative: options};
|
||
|
|
}
|
||
|
|
const {relative, invalid=false, strict=true} = options;
|
||
|
|
let {type, id, primaryId, collection, embedded, doc} = foundry.utils.parseUuid(uuid, {relative});
|
||
|
|
if ( (collection instanceof CompendiumCollection) && embedded.length ) {
|
||
|
|
if ( !strict ) return null;
|
||
|
|
throw new Error(
|
||
|
|
`fromUuidSync was invoked on UUID '${uuid}' which references an Embedded Document and cannot be retrieved `
|
||
|
|
+ "synchronously.");
|
||
|
|
}
|
||
|
|
|
||
|
|
const baseId = primaryId ?? id;
|
||
|
|
if ( collection instanceof CompendiumCollection ) {
|
||
|
|
if ( type === "Folder" ) return collection.folders.get(id);
|
||
|
|
doc = doc ?? collection.get(baseId, {invalid}) ?? collection.index.get(baseId);
|
||
|
|
if ( doc ) doc.pack = collection.collection;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
doc = doc ?? collection?.get(baseId, {invalid});
|
||
|
|
if ( embedded.length ) doc = _resolveEmbedded(doc, embedded, {invalid});
|
||
|
|
}
|
||
|
|
return doc || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Resolve a series of embedded document UUID parts against a parent Document.
|
||
|
|
* @param {Document} parent The parent Document.
|
||
|
|
* @param {string[]} parts A series of Embedded Document UUID parts.
|
||
|
|
* @param {object} [options] Additional options to configure Embedded Document resolution.
|
||
|
|
* @param {boolean} [options.invalid=false] Allow retrieving an invalid Embedded Document.
|
||
|
|
* @returns {Document} The resolved Embedded Document.
|
||
|
|
* @private
|
||
|
|
*/
|
||
|
|
function _resolveEmbedded(parent, parts, {invalid=false}={}) {
|
||
|
|
let doc = parent;
|
||
|
|
while ( doc && (parts.length > 1) ) {
|
||
|
|
const [embeddedName, embeddedId] = parts.splice(0, 2);
|
||
|
|
doc = doc.getEmbeddedDocument(embeddedName, embeddedId, {invalid});
|
||
|
|
}
|
||
|
|
return doc;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* -------------------------------------------- */
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Return a reference to the Document class implementation which is configured for use.
|
||
|
|
* @param {string} documentName The canonical Document name, for example "Actor"
|
||
|
|
* @returns {typeof foundry.abstract.Document} The configured Document class implementation
|
||
|
|
*/
|
||
|
|
function getDocumentClass(documentName) {
|
||
|
|
return CONFIG[documentName]?.documentClass;
|
||
|
|
}
|