UNPKG

40 kBSource Map (JSON)View Raw
1{"version":3,"file":"imready.min.js","sources":["../src/consts.ts","../src/utils.ts","../src/AutoSizer.ts","../src/loaders/Loader.ts","../src/index.umd.ts","../src/loaders/ElementLoader.ts","../src/ImReadyManager.ts","../src/loaders/ImageLoader.ts","../src/loaders/VideoLoader.ts","../src/ImReady.ts"],"sourcesContent":["/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nconst isWindow = typeof window !== \"undefined\";\nconst ua = isWindow ? window.navigator.userAgent : \"\";\nexport const SUPPORT_COMPUTEDSTYLE = isWindow ? !!(\"getComputedStyle\" in window) : false;\nexport const IS_IE = /MSIE|Trident|Windows Phone|Edge/.test(ua);\nexport const SUPPORT_ADDEVENTLISTENER = isWindow ? !!(\"addEventListener\" in document) : false;\nexport const WIDTH = \"width\";\nexport const HEIGHT = \"height\";\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport { ArrayFormat } from \"./types\";\n\nimport { SUPPORT_ADDEVENTLISTENER, SUPPORT_COMPUTEDSTYLE } from \"./consts\";\n\nexport function getAttribute(el: HTMLElement, name: string): string {\n return el.getAttribute(name) || \"\";\n}\n\nexport function toArray<T>(arr: ArrayFormat<T>): T[] {\n return [].slice.call(arr);\n}\nexport function hasSizeAttribute(target: HTMLElement, prefix = \"data-\"): boolean {\n return !!target.getAttribute(`${prefix}width`);\n}\nexport function hasLoadingAttribute(target: HTMLElement): target is HTMLImageElement {\n return (\"loading\" in target) && (target as HTMLImageElement).getAttribute(\"loading\") === \"lazy\";\n}\nexport function hasSkipAttribute(target: HTMLElement, prefix = \"data-\"): boolean {\n return !!target.getAttribute(`${prefix}skip`);\n}\nexport function addEvent(\n element: EventTarget,\n type: string,\n handler: (...args: any[]) => void,\n) {\n if (SUPPORT_ADDEVENTLISTENER) {\n element.addEventListener(type, handler, false);\n } else if ((element as any).attachEvent) {\n (element as any).attachEvent(`on${type}`, handler);\n } else {\n (element as any)[`on${type}`] = handler;\n }\n}\nexport function removeEvent(\n element: EventTarget,\n type: string,\n handler: (...args: any[]) => void,\n) {\n if (element.removeEventListener) {\n element.removeEventListener(type, handler, false);\n } else if ((element as any).detachEvent) {\n (element as any).detachEvent(`on${type}`, handler);\n } else {\n (element as any)[`on${type}`] = null;\n }\n}\n\nexport function innerWidth(el: HTMLElement) {\n return getSize(el, \"Width\");\n}\nexport function innerHeight(el: HTMLElement) {\n return getSize(el, \"Height\");\n}\nexport function getStyles(el: Element) {\n return (SUPPORT_COMPUTEDSTYLE ?\n window.getComputedStyle(el) : (el as any).currentStyle) || {};\n}\nfunction getSize(el: HTMLElement, name: \"Width\" | \"Height\") {\n const size = (el as any)[`client${name}`] || (el as any)[`offset${name}`];\n\n return parseFloat(size || getStyles(el)[name.toLowerCase()]) || 0;\n}\n\nexport function getContentElements(element: HTMLElement, tags: string[], prefix: string) {\n const skipElements = toArray(element.querySelectorAll([\n `[${prefix}skip] [${prefix}width]`,\n ...tags.map(tag => ([\n `[${prefix}skip] ${tag}`,\n `${tag}[${prefix}skip]`,\n `[${prefix}width] ${tag}`,\n ]).join(\", \")),\n ].join(\", \")));\n\n return toArray<HTMLElement>(\n element.querySelectorAll(`[${prefix}width], ${tags.join(\", \")}`),\n ).filter(el => {\n return skipElements.indexOf(el) === -1;\n });\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport { addEvent, removeEvent, innerWidth, innerHeight, getAttribute } from \"./utils\";\nimport { WIDTH, HEIGHT } from \"./consts\";\nimport { AutoSizerElement } from \"./types\";\n\nconst elements: AutoSizerElement[] = [];\n\nexport function addAutoSizer(element: AutoSizerElement, prefix: string) {\n !elements.length && addEvent(window, \"resize\", resizeAllAutoSizers);\n element.__PREFIX__ = prefix;\n elements.push(element);\n resize(element);\n}\nexport function removeAutoSizer(element: AutoSizerElement, prefix: string) {\n const index = elements.indexOf(element);\n\n if (index < 0) {\n return;\n }\n const fixed = getAttribute(element, `${prefix}fixed`);\n\n delete element.__PREFIX__;\n element.style[fixed === HEIGHT ? WIDTH : HEIGHT] = \"\";\n elements.splice(index, 1);\n\n !elements.length && removeEvent(window, \"resize\", resizeAllAutoSizers);\n}\nfunction resize(element: AutoSizerElement, prefix = \"data-\") {\n const elementPrefix = element.__PREFIX__ || prefix;\n const dataWidth = parseInt(getAttribute(element, `${elementPrefix}${WIDTH}`), 10) || 0;\n const dataHeight = parseInt(getAttribute(element, `${elementPrefix}${HEIGHT}`), 10) || 0;\n const fixed = getAttribute(element, `${elementPrefix}fixed`);\n\n if (fixed === HEIGHT) {\n const size = innerHeight(element) || dataHeight;\n\n element.style[WIDTH] = `${dataWidth / dataHeight * size}px`;\n } else {\n const size = innerWidth(element) || dataWidth;\n\n element.style[HEIGHT] = `${dataHeight / dataWidth * size}px`;\n }\n}\nexport function resizeAllAutoSizers() {\n elements.forEach(element => {\n resize(element);\n });\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport Component from \"@egjs/component\";\nimport { addAutoSizer, removeAutoSizer } from \"../AutoSizer\";\nimport { ImReadyLoaderEvents, ImReadyLoaderOptions } from \"../types\";\nimport { removeEvent, hasSizeAttribute, hasLoadingAttribute, addEvent, hasSkipAttribute } from \"../utils\";\n\n\nexport default abstract class Loader<T extends HTMLElement = any> extends Component<ImReadyLoaderEvents> {\n public static EVENTS: string[] = [];\n public options!: ImReadyLoaderOptions;\n public abstract checkElement(): boolean;\n protected element!: T;\n protected isReady = false;\n protected isPreReady = false;\n protected hasDataSize = false;\n protected hasLoading = false;\n protected isSkip = false;\n\n constructor(element: HTMLElement, options: Partial<ImReadyLoaderOptions> = {}) {\n super();\n this.options = {\n prefix: \"data-\",\n ...options,\n };\n this.element = element as T;\n const prefix = this.options.prefix;\n\n this.hasDataSize = hasSizeAttribute(element, prefix);\n this.isSkip = hasSkipAttribute(element, prefix);\n this.hasLoading = hasLoadingAttribute(element);\n }\n public check() {\n if (this.isSkip || !this.checkElement()) {\n // I'm Ready\n this.onAlreadyReady(true);\n return false;\n }\n\n if (this.hasDataSize) {\n addAutoSizer(this.element, this.options.prefix);\n }\n if (this.hasDataSize || this.hasLoading) {\n // I'm Pre Ready\n this.onAlreadyPreReady();\n }\n // Wati Pre Ready, Ready\n return true;\n }\n public addEvents() {\n const element = this.element;\n (this.constructor as typeof Loader).EVENTS.forEach(name => {\n addEvent(element, name, this.onCheck);\n });\n }\n public clear() {\n const element = this.element;\n (this.constructor as typeof Loader).EVENTS.forEach(name => {\n removeEvent(element, name, this.onCheck);\n });\n this.removeAutoSizer();\n }\n public destroy() {\n this.clear();\n this.off();\n }\n public removeAutoSizer() {\n if (this.hasDataSize) {\n // I'm already ready.\n const { prefix } = this.options;\n\n removeAutoSizer(this.element, prefix);\n }\n }\n public onCheck = (e?: Event) => {\n this.clear();\n\n\n if (e && e.type === \"error\") {\n this.onError(this.element);\n }\n // I'm pre-ready and ready!\n const withPreReady = !this.hasDataSize && !this.hasLoading;\n\n this.onReady(withPreReady);\n };\n public onError(target: HTMLElement) {\n this.trigger(\"error\", {\n element: this.element,\n target: target,\n });\n }\n public onPreReady() {\n if (this.isPreReady) {\n return;\n }\n this.isPreReady = true;\n this.trigger(\"preReady\", {\n element: this.element,\n hasLoading: this.hasLoading,\n isSkip: this.isSkip,\n });\n }\n public onReady(withPreReady: boolean) {\n if (this.isReady) {\n return;\n }\n withPreReady = !this.isPreReady && withPreReady;\n\n if (withPreReady) {\n this.isPreReady = true;\n }\n this.removeAutoSizer();\n this.isReady = true;\n this.trigger(\"ready\", {\n element: this.element,\n withPreReady,\n hasLoading: this.hasLoading,\n isSkip: this.isSkip,\n });\n }\n public onAlreadyError(target: HTMLElement) {\n setTimeout(() => {\n this.onError(target);\n });\n }\n public onAlreadyPreReady() {\n setTimeout(() => {\n this.onPreReady();\n });\n }\n public onAlreadyReady(withPreReady: boolean) {\n setTimeout(() => {\n this.onReady(withPreReady);\n });\n }\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport ImReady, * as modules from \"./index\";\n\nfor (const name in modules) {\n (ImReady as any)[name] = (modules as any)[name];\n}\n\nexport default ImReady;\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport { addAutoSizer } from \"../AutoSizer\";\nimport { ImReadyLoaderOptions } from \"../types\";\nimport Loader from \"./Loader\";\n\n\nexport class ElementLoader<T extends HTMLElement> extends Loader<T> {\n public static EVENTS: string[] = [];\n public options!: ImReadyLoaderOptions;\n\n public setHasLoading(hasLoading: boolean) {\n this.hasLoading = hasLoading;\n }\n public check() {\n if (this.isSkip) {\n // I'm Ready\n this.onAlreadyReady(true);\n return false;\n }\n\n if (this.hasDataSize) {\n addAutoSizer(this.element, this.options.prefix);\n this.onAlreadyPreReady();\n } else {\n // has not data size\n this.trigger(\"requestChildren\");\n }\n return true;\n }\n public checkElement() {\n return true;\n }\n public destroy() {\n this.clear();\n this.trigger(\"requestDestroy\");\n this.off();\n }\n public onAlreadyPreReady() {\n // has data size\n super.onAlreadyPreReady();\n this.trigger(\"reqeustReadyChildren\");\n }\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport Component from \"@egjs/component\";\nimport { ElementLoader } from \"./loaders/ElementLoader\";\nimport { ArrayFormat, ElementInfo, ImReadyEvents, ImReadyLoaderOptions, ImReadyOptions } from \"./types\";\nimport { toArray, getContentElements, hasLoadingAttribute } from \"./utils\";\n/**\n * @alias eg.ImReady\n * @extends eg.Component\n */\nclass ImReadyManager extends Component<ImReadyEvents> {\n public options!: ImReadyOptions;\n private readyCount = 0;\n private preReadyCount = 0;\n private totalCount = 0;\n private totalErrorCount = 0;\n private isPreReadyOver = true;\n private elementInfos: ElementInfo[] = [];\n /**\n * @param - ImReady's options\n */\n constructor(options: Partial<ImReadyOptions> = {}) {\n super();\n this.options = {\n loaders: {},\n prefix: \"data-\",\n ...options,\n };\n }\n /**\n * Checks whether elements are in the ready state.\n * @ko 엘리먼트가 준비 상태인지 체크한다.\n * @elements - Elements to check ready status. <ko> 준비 상태를 체크할 엘리먼트들.</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\" data-width=\"1280\" data-height=\"853\"/>\n * <img src=\"ERR\" data-width=\"1280\" data-height=\"853\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check(document.querySelectorAll(\"img\")).on({\n * preReadyElement: e => {\n * // 1, 3\n * // 2, 3\n * // 3, 3\n * console.log(e.preReadyCount, e.totalCount),\n * },\n * });\n * ```\n */\n public check(elements: ArrayFormat<HTMLElement>): this {\n const { prefix } = this.options;\n\n this.clear();\n this.elementInfos = toArray(elements).map((element, index) => {\n const loader = this.getLoader(element, { prefix });\n\n loader.check();\n loader.on(\"error\", e => {\n this.onError(index, e.target);\n }).on(\"preReady\", e => {\n const info = this.elementInfos[index];\n\n info.hasLoading = e.hasLoading;\n info.isSkip = e.isSkip;\n const isPreReady = this.checkPreReady(index);\n\n this.onPreReadyElement(index);\n\n isPreReady && this.onPreReady();\n }).on(\"ready\", ({ withPreReady, hasLoading, isSkip }) => {\n const info = this.elementInfos[index];\n\n info.hasLoading = hasLoading;\n info.isSkip = isSkip;\n\n const isPreReady = withPreReady && this.checkPreReady(index);\n const isReady = this.checkReady(index);\n\n // Pre-ready and ready occur simultaneously\n withPreReady && this.onPreReadyElement(index);\n this.onReadyElement(index);\n\n isPreReady && this.onPreReady();\n isReady && this.onReady();\n });\n\n return {\n loader,\n element,\n hasLoading: false,\n hasError: false,\n isPreReady: false,\n isReady: false,\n isSkip: false,\n };\n });\n\n const length = this.elementInfos.length;\n\n this.totalCount = length;\n if (!length) {\n setTimeout(() => {\n this.onPreReady();\n this.onReady();\n });\n }\n return this;\n }\n /**\n * Gets the total count of elements to be checked.\n * @ko 체크하는 element의 총 개수를 가져온다.\n */\n public getTotalCount() {\n return this.totalCount;\n }\n /**\n * Whether the elements are all pre-ready. (all sizes are known)\n * @ko 엘리먼트들이 모두 사전 준비가 됐는지 (사이즈를 전부 알 수 있는지) 여부.\n */\n public isPreReady() {\n return this.elementInfos.every(info => info.isPreReady);\n }\n /**\n * Whether the elements are all ready.\n * @ko 엘리먼트들이 모두 준비가 됐는지 여부.\n */\n public isReady() {\n return this.elementInfos.every(info => info.isReady);\n }\n /**\n * Whether an error has occurred in the elements in the current state.\n * @ko 현재 상태에서 엘리먼트들이 에러가 발생했는지 여부.\n */\n public hasError() {\n return this.totalErrorCount > 0;\n }\n /**\n * Clears events of elements being checked.\n * @ko 체크 중인 엘리먼트들의 이벤트를 해제 한다.\n */\n public clear() {\n this.isPreReadyOver = false;\n this.totalCount = 0;\n this.preReadyCount = 0;\n this.readyCount = 0;\n this.totalErrorCount = 0;\n this.elementInfos.forEach(info => {\n if (!info.isReady && info.loader) {\n info.loader.destroy();\n }\n });\n this.elementInfos = [];\n }\n /**\n * Destory all events.\n * @ko 모든 이벤트를 해제 한다.\n */\n public destroy() {\n this.clear();\n this.off();\n }\n private getLoader(element: HTMLElement, options: ImReadyLoaderOptions) {\n const tagName = element.tagName.toLowerCase();\n const loaders = this.options.loaders;\n const tags = Object.keys(loaders);\n\n if (loaders[tagName]) {\n return new loaders[tagName](element, options);\n }\n const loader = new ElementLoader(element, options);\n const children = toArray(element.querySelectorAll<HTMLElement>(tags.join(\", \")));\n\n loader.setHasLoading(children.some(el => hasLoadingAttribute(el)));\n let withPreReady = false;\n\n const childrenImReady = this.clone().on(\"error\", e => {\n loader.onError(e.target);\n }).on(\"ready\", () => {\n loader.onReady(withPreReady);\n });\n\n loader.on(\"requestChildren\", () => {\n // has not data size\n const contentElements = getContentElements(element, tags, this.options.prefix);\n\n childrenImReady.check(contentElements).on(\"preReady\", e => {\n withPreReady = e.isReady;\n if (!withPreReady) {\n loader.onPreReady();\n }\n });\n }).on(\"reqeustReadyChildren\", () => {\n // has data size\n // loader call preReady\n // check only video, image elements\n childrenImReady.check(children);\n }).on(\"requestDestroy\", () => {\n childrenImReady.destroy();\n });\n\n return loader;\n }\n private clone() {\n return new ImReadyManager({ ...this.options });\n }\n private checkPreReady(index: number) {\n this.elementInfos[index].isPreReady = true;\n ++this.preReadyCount;\n\n\n if (this.preReadyCount < this.totalCount) {\n return false;\n }\n return true;\n }\n private checkReady(index: number) {\n this.elementInfos[index].isReady = true;\n ++this.readyCount;\n\n if (this.readyCount < this.totalCount) {\n return false;\n }\n return true;\n }\n\n\n private onError(index: number, target: HTMLElement) {\n const info = this.elementInfos[index];\n\n info.hasError = true;\n /**\n * An event occurs if the image, video fails to load.\n * @ko 이미지, 비디오가 로딩에 실패하면 이벤트가 발생한다.\n * @event eg.ImReady#error\n * @param {eg.ImReady.OnError} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>\n * @param {HTMLElement} [e.element] - The element with error images.<ko>오류난 이미지가 있는 엘리먼트</ko>\n * @param {number} [e.index] - The item's index with error images. <ko>오류난 이미지가 있는 엘리먼트의 인덱스</ko>\n * @param {HTMLElement} [e.target] - Error image target in element <ko>엘리먼트의 오류난 이미지 타겟</ko>\n * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>\n * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\"/>\n * <img src=\"ERR\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check([document.querySelector(\"div\")]).on({\n * error: e => {\n * // <div>...</div>, 0, <img src=\"ERR\"/>\n * console.log(e.element, e.index, e.target),\n * },\n * });\n * ```\n */\n this.trigger(\"error\", {\n element: info.element,\n index,\n target,\n errorCount: this.getErrorCount(),\n totalErrorCount: ++this.totalErrorCount,\n });\n }\n private onPreReadyElement(index: number) {\n const info = this.elementInfos[index];\n /**\n * An event occurs when the element is pre-ready (when the loading attribute is applied or the size is known)\n * @ko 해당 엘리먼트가 사전 준비되었을 때(loading 속성이 적용되었거나 사이즈를 알 수 있을 때) 이벤트가 발생한다.\n * @event eg.ImReady#preReadyElement\n * @param {eg.ImReady.OnPreReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>\n * @param {HTMLElement} [e.element] - The pre-ready element.<ko>사전 준비된 엘리먼트</ko>\n * @param {number} [e.index] - The index of the pre-ready element. <ko>사전 준비된 엘리먼트의 인덱스</ko>\n * @param {number} [e.preReadyCount] - Number of elements pre-ready <ko>사전 준비된 엘리먼트들의 개수</ko>\n * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>\n * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>\n * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready <ko>모든 엘리먼트가 사전 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>\n * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute <ko>skip 속성으로 인하여 체크가 생략됐는지 여부</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\" data-width=\"1280\" data-height=\"853\"/>\n * <img src=\"ERR\" data-width=\"1280\" data-height=\"853\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check(document.querySelectorAll(\"img\")).on({\n * preReadyElement: e => {\n * // 1, 3\n * // 2, 3\n * // 3, 3\n * console.log(e.preReadyCount, e.totalCount),\n * },\n * });\n * ```\n */\n this.trigger(\"preReadyElement\", {\n element: info.element,\n index,\n\n preReadyCount: this.preReadyCount,\n readyCount: this.readyCount,\n totalCount: this.totalCount,\n\n isPreReady: this.isPreReady(),\n isReady: this.isReady(),\n hasLoading: info.hasLoading,\n isSkip: info.isSkip,\n });\n }\n private onPreReady() {\n this.isPreReadyOver = true;\n /**\n * An event occurs when all element are pre-ready (When all elements have the loading attribute applied or the size is known)\n * @ko 모든 엘리먼트들이 사전 준비된 경우 (모든 엘리먼트들이 loading 속성이 적용되었거나 사이즈를 알 수 있는 경우) 이벤트가 발생한다.\n * @event eg.ImReady#preReady\n * @param {eg.ImReady.OnPreReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>\n * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>\n * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>\n * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\" data-width=\"1280\" data-height=\"853\"/>\n * <img src=\"ERR\" data-width=\"1280\" data-height=\"853\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check(document.querySelectorAll(\"img\")).on({\n * preReady: e => {\n * // 0, 3\n * console.log(e.readyCount, e.totalCount),\n * },\n * });\n * ```\n */\n this.trigger(\"preReady\", {\n readyCount: this.readyCount,\n totalCount: this.totalCount,\n isReady: this.isReady(),\n hasLoading: this.hasLoading(),\n });\n }\n private onReadyElement(index: number) {\n const info = this.elementInfos[index];\n /**\n * An event occurs when the element is ready\n * @ko 해당 엘리먼트가 준비가 되었을 때 이벤트가 발생한다.\n * @event eg.ImReady#readyElement\n * @param {eg.ImReady.OnReadyElement} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>\n * @param {HTMLElement} [e.element] - The ready element.<ko>준비된 엘리먼트</ko>\n * @param {number} [e.index] - The index of the ready element. <ko>준비된 엘리먼트의 인덱스</ko>\n * @param {boolean} [e.hasError] - Whether there is an error in the element <ko>해당 엘리먼트에 에러가 있는지 여부</ko>\n * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>\n * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>\n * @param {number} [e.preReadyCount] - Number of elements pre-ready <ko>사전 준비된 엘리먼트들의 개수</ko>\n * @param {number} [e.readyCount] - Number of elements ready <ko>준비된 엘리먼트들의 개수</ko>\n * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>\n * @param {boolean} [e.isPreReady] - Whether all elements are pre-ready <ko>모든 엘리먼트가 사전 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.isReady] - Whether all elements are ready <ko>모든 엘리먼트가 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.hasLoading] - Whether the loading attribute has been applied <ko>loading 속성이 적용되었는지 여부</ko>\n * @param {boolean} [e.isPreReadyOver] - Whether pre-ready is over <ko>사전 준비가 끝났는지 여부</ko>\n * @param {boolean} [e.isSkip] - Whether the check is omitted due to skip attribute <ko>skip 속성으로 인하여 체크가 생략됐는지 여부</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\" data-width=\"1280\" data-height=\"853\"/>\n * <img src=\"ERR\" data-width=\"1280\" data-height=\"853\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check(document.querySelectorAll(\"img\")).on({\n * readyElement: e => {\n * // 1, 0, false, 3\n * // 2, 1, false, 3\n * // 3, 2, true, 3\n * console.log(e.readyCount, e.index, e.hasError, e.totalCount),\n * },\n * });\n * ```\n */\n this.trigger(\"readyElement\", {\n index,\n element: info.element,\n\n hasError: info.hasError,\n errorCount: this.getErrorCount(),\n totalErrorCount: this.totalErrorCount,\n\n preReadyCount: this.preReadyCount,\n readyCount: this.readyCount,\n totalCount: this.totalCount,\n\n isPreReady: this.isPreReady(),\n isReady: this.isReady(),\n\n hasLoading: info.hasLoading,\n isPreReadyOver: this.isPreReadyOver,\n isSkip: info.isSkip,\n });\n }\n private onReady() {\n /**\n * An event occurs when all element are ready\n * @ko 모든 엘리먼트들이 준비된 경우 이벤트가 발생한다.\n * @event eg.ImReady#ready\n * @param {eg.ImReady.OnReady} e - The object of data to be sent to an event <ko>이벤트에 전달되는 데이터 객체</ko>\n * @param {number} [e.errorCount] - The number of elements with errors <ko>에러가 있는 엘리먼트들의 개수</ko>\n * @param {number} [e.totalErrorCount] - The total number of targets with errors <ko>에러가 있는 타겟들의 총 개수</ko>\n * @param {number} [e.totalCount] - Total number of elements <ko>엘리먼트들의 총 개수</ko>\n * @example\n * ```html\n * <div>\n * <img src=\"./1.jpg\" data-width=\"1280\" data-height=\"853\" style=\"width:100%\"/>\n * <img src=\"./2.jpg\" data-width=\"1280\" data-height=\"853\"/>\n * <img src=\"ERR\" data-width=\"1280\" data-height=\"853\"/>\n * </div>\n * ```\n * ## Javascript\n * ```js\n * import ImReady from \"@egjs/imready\";\n *\n * const im = new ImReady(); // umd: eg.ImReady\n * im.check(document.querySelectorAll(\"img\")).on({\n * preReady: e => {\n * // 0, 3\n * console.log(e.readyCount, e.totalCount),\n * },\n * ready: e => {\n * // 1, 3\n * console.log(e.errorCount, e.totalCount),\n * },\n * });\n * ```\n */\n this.trigger(\"ready\", {\n errorCount: this.getErrorCount(),\n totalErrorCount: this.totalErrorCount,\n totalCount: this.totalCount,\n });\n }\n private getErrorCount() {\n return this.elementInfos.filter(info => info.hasError).length;\n }\n private hasLoading() {\n return this.elementInfos.some(info => info.hasLoading);\n }\n}\n\nexport default ImReadyManager;\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport { IS_IE } from \"../consts\";\nimport Loader from \"./Loader\";\n\nexport default class ImageLoader extends Loader<HTMLImageElement> {\n public static EVENTS = [\"load\", \"error\"];\n public checkElement() {\n const element = this.element;\n const src = element.getAttribute(\"src\");\n\n if (element.complete) {\n if (src) {\n // complete\n if (!element.naturalWidth) {\n this.onAlreadyError(element);\n }\n return false;\n } else {\n // Using an external lazy loading module\n this.onAlreadyPreReady();\n }\n }\n this.addEvents();\n IS_IE && element.setAttribute(\"src\", src!);\n return true;\n }\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport Loader from \"./Loader\";\n\nexport default class VideoLoader extends Loader<HTMLVideoElement> {\n public static EVENTS = [\"loadedmetadata\", \"error\"];\n public checkElement() {\n const element = this.element;\n // HAVE_NOTHING: 0, no information whether or not the audio/video is ready\n // HAVE_METADATA: 1, HAVE_METADATA - metadata for the audio/video is ready\n // HAVE_CURRENT_DATA: 2, data for the current playback position is available, but not enough data to play next frame/millisecond\n // HAVE_FUTURE_DATA: 3, data for the current and at least the next frame is available\n // HAVE_ENOUGH_DATA: 4, enough data available to start playing\n if (element.readyState >= 1) {\n return false;\n }\n if (element.error) {\n this.onAlreadyError(element);\n return false;\n }\n this.addEvents();\n return true;\n }\n}\n","/*\negjs-imready\nCopyright (c) 2020-present NAVER Corp.\nMIT license\n*/\nimport ImReadyManager from \"./ImReadyManager\";\nimport ImageLoader from \"./loaders/ImageLoader\";\nimport VideoLoader from \"./loaders/VideoLoader\";\nimport { ImReadyOptions } from \"./types\";\n\nclass ImReady extends ImReadyManager {\n constructor(options: Partial<ImReadyOptions> = {}) {\n super({\n loaders: {\n img: ImageLoader,\n video: VideoLoader,\n },\n ...options,\n });\n }\n}\n\nexport default ImReady;\n"],"names":["isWindow","window","ua","navigator","userAgent","SUPPORT_COMPUTEDSTYLE","IS_IE","test","SUPPORT_ADDEVENTLISTENER","document","WIDTH","HEIGHT","getAttribute","el","name","toArray","arr","slice","call","hasLoadingAttribute","target","addEvent","element","type","handler","addEventListener","attachEvent","removeEvent","removeEventListener","detachEvent","getSize","size","parseFloat","getComputedStyle","currentStyle","toLowerCase","getContentElements","tags","prefix","skipElements","querySelectorAll","__spreadArrays","map","tag","join","filter","indexOf","elements","addAutoSizer","length","resizeAllAutoSizers","__PREFIX__","push","resize","elementPrefix","dataWidth","parseInt","dataHeight","style","forEach","options","_super","_this","e","clear","onError","withPreReady","hasDataSize","hasLoading","onReady","isSkip","__extends","this","checkElement","onAlreadyReady","onAlreadyPreReady","constructor","EVENTS","onCheck","removeAutoSizer","off","index","fixed","splice","trigger","isPreReady","isReady","setTimeout","onPreReady","Loader","Component","ElementLoader","loaders","elementInfos","loader","getLoader","check","on","info","checkPreReady","onPreReadyElement","_a","checkReady","onReadyElement","hasError","totalCount","every","totalErrorCount","isPreReadyOver","preReadyCount","readyCount","destroy","tagName","Object","keys","children","setHasLoading","some","childrenImReady","clone","contentElements","ImReadyManager","errorCount","getErrorCount","src","complete","naturalWidth","onAlreadyError","addEvents","setAttribute","ImageLoader","readyState","error","VideoLoader","img","video","modules","ImReady"],"mappings":"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"}
\No newline at end of file