{"version":3,"file":"objectEnlive.mjs","sources":["../../../../src/util/misc/objectEnlive.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n  Abortable,\n  Constructor,\n  TCrossOrigin,\n  TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n  /**\n   * cors value for the image loading, default to anonymous\n   */\n  crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise<HTMLImageElement>} the loaded image.\n */\nexport const loadImage = (\n  url: string,\n  { signal, crossOrigin = null }: LoadImageOptions = {},\n) =>\n  new Promise<HTMLImageElement>(function (resolve, reject) {\n    if (signal && signal.aborted) {\n      return reject(new SignalAbortedError('loadImage'));\n    }\n    const img = createImage();\n    let abort: EventListenerOrEventListenerObject;\n    if (signal) {\n      abort = function (err: Event) {\n        img.src = '';\n        reject(err);\n      };\n      signal.addEventListener('abort', abort, { once: true });\n    }\n    const done = function () {\n      img.onload = img.onerror = null;\n      abort && signal?.removeEventListener('abort', abort);\n      resolve(img);\n    };\n    if (!url) {\n      done();\n      return;\n    }\n    img.onload = done;\n    img.onerror = function () {\n      abort && signal?.removeEventListener('abort', abort);\n      reject(new FabricError(`Error loading ${img.src}`));\n    };\n    crossOrigin && (img.crossOrigin = crossOrigin);\n    img.src = url;\n  });\n\nexport type EnlivenObjectOptions = Abortable & {\n  /**\n   * Method for further parsing of object elements,\n   * called after each fabric object created.\n   */\n  reviver?: <\n    T extends\n      | BaseFabricObject\n      | FabricObject\n      | BaseFilter<string>\n      | Shadow\n      | TFiller,\n  >(\n    serializedObj: Record<string, any>,\n    instance: T,\n  ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<FabricObject[]>}\n */\nexport const enlivenObjects = <\n  T extends\n    | BaseFabricObject\n    | FabricObject\n    | BaseFilter<string>\n    | Shadow\n    | TFiller,\n>(\n  objects: any[],\n  { signal, reviver = noop }: EnlivenObjectOptions = {},\n) =>\n  new Promise<T[]>((resolve, reject) => {\n    const instances: T[] = [];\n    signal && signal.addEventListener('abort', reject, { once: true });\n    Promise.all(\n      objects.map((obj) =>\n        classRegistry\n          .getClass<\n            Constructor<T> & {\n              fromObject(options: any, context: Abortable): Promise<T>;\n            }\n          >(obj.type)\n          .fromObject(obj, { signal })\n          .then((fabricInstance) => {\n            reviver(obj, fabricInstance);\n            instances.push(fabricInstance);\n            return fabricInstance;\n          }),\n      ),\n    )\n      .then(resolve)\n      .catch((error) => {\n        // cleanup\n        instances.forEach((instance) => {\n          (instance as FabricObject).dispose &&\n            (instance as FabricObject).dispose();\n        });\n        reject(error);\n      })\n      .finally(() => {\n        signal && signal.removeEventListener('abort', reject);\n      });\n  });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise<Record<string, FabricObject | TFiller | null>>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n  R = Record<string, FabricObject | TFiller | null>,\n>(\n  serializedObject: any,\n  { signal }: Abortable = {},\n) =>\n  new Promise<R>((resolve, reject) => {\n    const instances: (FabricObject | TFiller | Shadow)[] = [];\n    signal && signal.addEventListener('abort', reject, { once: true });\n    // enlive every possible property\n    const promises = Object.values(serializedObject).map((value: any) => {\n      if (!value) {\n        return value;\n      }\n      /**\n       * clipPath or shadow or gradient or text on a path or a pattern,\n       * or the backgroundImage or overlayImage of canvas\n       * If we have a type and there is a classe registered for it, we enlive it.\n       * If there is no class registered for it we return the value as is\n       * */\n      if (value.type && classRegistry.has(value.type)) {\n        return enlivenObjects<FabricObject | Shadow | TFiller>([value], {\n          signal,\n        }).then(([enlived]) => {\n          instances.push(enlived);\n          return enlived;\n        });\n      }\n      return value;\n    });\n    const keys = Object.keys(serializedObject);\n    Promise.all(promises)\n      .then((enlived) => {\n        return enlived.reduce((acc, instance, index) => {\n          acc[keys[index]] = instance;\n          return acc;\n        }, {});\n      })\n      .then(resolve)\n      .catch((error) => {\n        // cleanup\n        instances.forEach((instance: any) => {\n          instance.dispose && instance.dispose();\n        });\n        reject(error);\n      })\n      .finally(() => {\n        signal && signal.removeEventListener('abort', reject);\n      });\n  });\n"],"names":["loadImage","url","signal","crossOrigin","arguments","length","undefined","Promise","resolve","reject","aborted","SignalAbortedError","img","createImage","abort","err","src","addEventListener","once","done","onload","onerror","removeEventListener","FabricError","concat","enlivenObjects","objects","reviver","noop","instances","all","map","obj","classRegistry","getClass","type","fromObject","then","fabricInstance","push","catch","error","forEach","instance","dispose","finally","enlivenObjectEnlivables","serializedObject","promises","Object","values","value","has","_ref","enlived","keys","reduce","acc","index"],"mappings":"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"}