UNPKG

@egjs/infinitegrid

Version:

A module used to arrange elements including content infinitely according to grid type. With this module, you can implement various grids composed of different card elements whose sizes vary. It guarantees performance by maintaining the number of DOMs the

1,525 lines (1,513 loc) 123 kB
/* Copyright (c) NAVER Corp. name: @egjs/infinitegrid license: MIT author: NAVER Corp. repository: https://github.com/naver/egjs-infinitegrid version: 4.13.0 */ 'use strict'; var Component = require('@egjs/component'); var Grid = require('@egjs/grid'); var core = require('@cfcs/core'); var listDiffer = require('@egjs/list-differ'); /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; } || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var ua = typeof window !== "undefined" ? window.navigator.userAgent : ""; var IS_IOS = /iPhone|iPad/.test(ua); var CONTAINER_CLASS_NAME = "infinitegrid-container"; var IGNORE_PROPERITES_MAP = { renderOnPropertyChange: true, useFit: true, autoResize: true }; var INFINITEGRID_PROPERTY_TYPES = __assign({}, Grid.GRID_PROPERTY_TYPES); var DIRECTION = { START: "start", END: "end", NONE: "" }; var INFINITEGRID_EVENTS = { CHANGE_SCROLL: "changeScroll", REQUEST_APPEND: "requestAppend", REQUEST_PREPEND: "requestPrepend", RENDER_COMPLETE: "renderComplete", CONTENT_ERROR: "contentError" }; var ITEM_INFO_PROPERTIES = { type: true, groupKey: true, key: true, element: true, html: true, data: true, inserted: true, attributes: true }; var INFINITEGRID_METHODS = ["resizeScroll", "insertByGroupIndex", "updateItems", "getItems", "getVisibleItems", "getGroups", "getVisibleGroups", "renderItems", "getContainerElement", "getScrollContainerElement", "getWrapperElement", "setStatus", "getStatus", "removePlaceholders", "prependPlaceholders", "appendPlaceholders", "getStartCursor", "getEndCursor", "setCursors"]; (function (GROUP_TYPE) { GROUP_TYPE[GROUP_TYPE["NORMAL"] = 0] = "NORMAL"; GROUP_TYPE[GROUP_TYPE["VIRTUAL"] = 1] = "VIRTUAL"; GROUP_TYPE[GROUP_TYPE["LOADING"] = 2] = "LOADING"; })(exports.GROUP_TYPE || (exports.GROUP_TYPE = {})); (function (ITEM_TYPE) { ITEM_TYPE[ITEM_TYPE["NORMAL"] = 0] = "NORMAL"; ITEM_TYPE[ITEM_TYPE["VIRTUAL"] = 1] = "VIRTUAL"; ITEM_TYPE[ITEM_TYPE["LOADING"] = 2] = "LOADING"; })(exports.ITEM_TYPE || (exports.ITEM_TYPE = {})); (function (STATUS_TYPE) { // does not remove anything. STATUS_TYPE[STATUS_TYPE["NOT_REMOVE"] = 0] = "NOT_REMOVE"; // Minimize information on invisible items STATUS_TYPE[STATUS_TYPE["MINIMIZE_INVISIBLE_ITEMS"] = 1] = "MINIMIZE_INVISIBLE_ITEMS"; // Minimize information on invisible groups STATUS_TYPE[STATUS_TYPE["MINIMIZE_INVISIBLE_GROUPS"] = 2] = "MINIMIZE_INVISIBLE_GROUPS"; // remove invisible groups STATUS_TYPE[STATUS_TYPE["REMOVE_INVISIBLE_GROUPS"] = 3] = "REMOVE_INVISIBLE_GROUPS"; })(exports.STATUS_TYPE || (exports.STATUS_TYPE = {})); var INVISIBLE_POS = -9999; /** * @extends Grid.GridItem */ var InfiniteGridItem = /*#__PURE__*/function (_super) { __extends(InfiniteGridItem, _super); function InfiniteGridItem(horizontal, itemStatus) { var _this = _super.call(this, horizontal, __assign({ html: "", type: exports.ITEM_TYPE.NORMAL, cssRect: { top: INVISIBLE_POS, left: INVISIBLE_POS } }, itemStatus)) || this; if (_this.type === exports.ITEM_TYPE.VIRTUAL) { if (_this.rect.width || _this.rect.height) { _this.mountState = Grid.MOUNT_STATE.UNMOUNTED; } var orgRect = _this.orgRect; var rect = _this.rect; var cssRect = _this.cssRect; if (cssRect.width) { rect.width = cssRect.width; } else if (orgRect.width) { rect.width = orgRect.width; } if (cssRect.height) { rect.height = cssRect.height; } else if (orgRect.height) { rect.height = orgRect.height; } } return _this; } var __proto = InfiniteGridItem.prototype; __proto.getVirtualStatus = function () { return { type: exports.ITEM_TYPE.VIRTUAL, groupKey: this.groupKey, key: this.key, orgRect: this.orgRect, rect: this.rect, cssRect: this.cssRect, attributes: this.attributes }; }; __proto.getMinimizedStatus = function () { var status = __assign(__assign({}, _super.prototype.getMinimizedStatus.call(this)), { type: exports.ITEM_TYPE.NORMAL, groupKey: this.groupKey }); if (this.html) { status.html = this.html; } return status; }; return InfiniteGridItem; }(Grid.GridItem); var LOADING_GROUP_KEY = "__INFINITEGRID__LOADING_GRID"; var LOADING_ITEM_KEY = "__INFINITEGRID__LOADING_ITEM"; var LoadingGrid = /*#__PURE__*/function (_super) { __extends(LoadingGrid, _super); function LoadingGrid() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.type = ""; _this.isWaitEnd = false; _this.initialDisplay = null; return _this; } var __proto = LoadingGrid.prototype; __proto.getLoadingItem = function () { return this.items[0] || null; }; __proto.startLoading = function () { var element = this.items[0].element; if (element) { if (this.initialDisplay != null) { this.initialDisplay = element.style.display || ""; } else if (this.initialDisplay) { element.style.display = this.initialDisplay; } else { element.style.removeProperty("display"); } } }; __proto.endLoading = function () { if (this.type) { var element = this.items[0].element; if (element) { element.style.display = "none"; } } }; __proto.setLoadingItem = function (item) { if (item) { var loadingItem = this.getLoadingItem(); if (!loadingItem) { this.items = [new InfiniteGridItem(this.options.horizontal, __assign(__assign({}, item), { type: exports.ITEM_TYPE.LOADING, key: LOADING_ITEM_KEY }))]; } else { for (var name in item) { loadingItem[name] = item[name]; } } } else { this.items = []; } }; __proto.applyGrid = function (items, direction, outline) { if (!items.length) { return { start: outline, end: outline }; } var nextOutline = outline.length ? __spreadArray([], outline, true) : [0]; var item = items[0]; var offset = item.contentSize + this.getContentGap(); item.cssInlinePos = this.getContainerInlineSize() / 2 - item.inlineSize / 2; if (direction === "end") { var maxPos = Math.max.apply(Math, nextOutline); item.cssContentPos = maxPos; return { start: nextOutline, end: nextOutline.map(function (pos) { return pos + offset; }) }; } else { var minPos = Math.min.apply(Math, nextOutline); item.cssContentPos = minPos - offset; return { start: nextOutline.map(function (pos) { return pos - offset; }), end: nextOutline }; } }; return LoadingGrid; }(Grid); function isWindow(el) { return el === window; } function isNumber(val) { return typeof val === "number"; } function isString(val) { return typeof val === "string"; } function isObject(val) { return typeof val === "object"; } function flat(arr) { return arr.reduce(function (prev, cur) { return __spreadArray(__spreadArray([], prev, true), cur, true); }, []); } function splitOptions(options) { var gridOptions = options.gridOptions, otherOptions = __rest(options, ["gridOptions"]); return __assign(__assign({}, splitGridOptions(gridOptions)), otherOptions); } function splitGridOptions(options) { var nextOptions = {}; var gridOptions = {}; var defaultOptions = Grid.defaultOptions; for (var name in options) { var value = options[name]; if (!(name in IGNORE_PROPERITES_MAP)) { gridOptions[name] = value; } if (name in defaultOptions) { nextOptions[name] = value; } } return __assign(__assign({}, nextOptions), { gridOptions: gridOptions }); } function categorize(items) { var groups = []; var groupKeys = {}; var registeredGroupKeys = {}; items.filter(function (item) { return item.groupKey != null; }).forEach(function (_a) { var groupKey = _a.groupKey; registeredGroupKeys[groupKey] = true; }); var generatedGroupKey; var isContinuousGroupKey = false; items.forEach(function (item, i) { if (item.groupKey != null) { isContinuousGroupKey = false; } else if (!item.inserted && items[i - 1]) { // In case of framework, inserted is false. // If groupKey is not set, the group key of the previous item is followed. item.groupKey = items[i - 1].groupKey; isContinuousGroupKey = false; } else { if (!isContinuousGroupKey) { generatedGroupKey = makeKey(registeredGroupKeys); isContinuousGroupKey = true; registeredGroupKeys[generatedGroupKey] = true; } item.groupKey = generatedGroupKey; } var groupKey = item.groupKey; var group = groupKeys[groupKey]; if (!group) { group = { groupKey: groupKey, items: [] }; groupKeys[groupKey] = group; groups.push(group); } group.items.push(item); }); return groups; } function getNextCursors(prevKeys, nextKeys, prevStartCursor, prevEndCursor) { var result = listDiffer.diff(prevKeys, nextKeys, function (key) { return key; }); var nextStartCursor = -1; var nextEndCursor = -1; // sync cursors result.maintained.forEach(function (_a) { var prevIndex = _a[0], nextIndex = _a[1]; if (prevStartCursor <= prevIndex && prevIndex <= prevEndCursor) { if (nextStartCursor === -1) { nextStartCursor = nextIndex; nextEndCursor = nextIndex; } else { nextStartCursor = Math.min(nextStartCursor, nextIndex); nextEndCursor = Math.max(nextEndCursor, nextIndex); } } }); return { startCursor: nextStartCursor, endCursor: nextEndCursor }; } function splitVirtualGroups(groups, direction, nextGroups) { var virtualGroups = []; if (direction === "start") { var index = findIndex(groups, function (group) { return group.type === exports.GROUP_TYPE.NORMAL; }); if (index === -1) { return []; } // Get the virtual group maintained in the group from the next group. var endMaintainedIndex = findIndex(groups, function (group) { return findIndex(nextGroups, function (nextGroup) { return nextGroup.groupKey === group.groupKey; }) >= 0; }); var endIndex = endMaintainedIndex >= 0 ? Math.min(index, endMaintainedIndex) : index; virtualGroups = groups.slice(0, endIndex); } else { var index = findLastIndex(groups, function (group) { return group.type === exports.GROUP_TYPE.NORMAL; }); if (index === -1) { return []; } var startMaintainedIndex = findLastIndex(groups, function (group) { return findIndex(nextGroups, function (nextGroup) { return nextGroup.groupKey === group.groupKey; }) >= 0; }); var startIndex = startMaintainedIndex >= 0 ? Math.max(index, startMaintainedIndex) : index; virtualGroups = groups.slice(startIndex + 1); } return virtualGroups; } function getFirstRenderingItems(nextItems, horizontal) { var groups = categorize(nextItems); if (!groups[0]) { return []; } return groups[0].items.map(function (item) { return new InfiniteGridItem(horizontal, __assign({}, item)); }); } function getRenderingItemsByStatus(groupManagerStatus, nextItems, usePlaceholder, horizontal) { var prevGroups = groupManagerStatus.groups; var groups = categorize(nextItems); var startVirtualGroups = splitVirtualGroups(prevGroups, "start", groups); var endVirtualGroups = splitVirtualGroups(prevGroups, "end", groups); var nextGroups = __spreadArray(__spreadArray(__spreadArray([], startVirtualGroups, true), groups, true), endVirtualGroups, true); var _a = getNextCursors(prevGroups.map(function (group) { return group.groupKey; }), nextGroups.map(function (group) { return group.groupKey; }), groupManagerStatus.cursors[0], groupManagerStatus.cursors[1]), startCursor = _a.startCursor, endCursor = _a.endCursor; var nextVisibleItems = flat(nextGroups.slice(startCursor, endCursor + 1).map(function (group) { return group.items.map(function (item) { return new InfiniteGridItem(horizontal, __assign({}, item)); }); })); if (!usePlaceholder) { nextVisibleItems = nextVisibleItems.filter(function (item) { return item.type !== exports.ITEM_TYPE.VIRTUAL; }); } return nextVisibleItems; } function mountRenderingItems(items, options) { var grid = options.grid, usePlaceholder = options.usePlaceholder, useLoading = options.useLoading, useFirstRender = options.useFirstRender, status = options.status; if (!grid) { return; } if (usePlaceholder) { grid.setPlaceholder({}); } if (useLoading) { grid.setLoading({}); } if (status) { grid.setStatus(status, true); } grid.syncItems(items); if (useFirstRender && !status && grid.getGroups().length) { grid.setCursors(0, 0, true); } } function getRenderingItems(items, options) { var status = options.status, usePlaceholder = options.usePlaceholder, useLoading = options.useLoading, horizontal = options.horizontal, useFirstRender = options.useFirstRender, grid = options.grid; var visibleItems = []; if (grid) { grid.setPlaceholder(usePlaceholder ? {} : null); grid.setLoading(useLoading ? {} : null); grid.syncItems(items); visibleItems = grid.getRenderingItems(); } else if (status) { visibleItems = getRenderingItemsByStatus(status.groupManager, items, !!usePlaceholder, !!horizontal); } else if (useFirstRender) { visibleItems = getFirstRenderingItems(items, !!horizontal); } return visibleItems; } /* Class Decorator */ function InfiniteGridGetterSetter(component) { var prototype = component.prototype, propertyTypes = component.propertyTypes, infinitegridTypes = component.infinitegridTypes; var _loop_1 = function (name) { var attributes = { enumerable: true, configurable: true, get: function get() { var options = this.options; return options[name]; }, set: function set(value) { var setterName = "_".concat(core.camelize("set ".concat(name))); if (this[setterName]) { this[setterName](value); } else { this.options[name] = value; } } }; Object.defineProperty(prototype, name, attributes); }; for (var name in infinitegridTypes) { _loop_1(name); } var _loop_2 = function (name) { var attributes = { enumerable: true, configurable: true, get: function () { var options = this.groupManager.options; if (name in options) { return options[name]; } else { return options.gridOptions[name]; } }, set: function (value) { var _a; var prevValue = this.groupManager[name]; if (prevValue === value) { return; } this.groupManager.gridOptions = (_a = {}, _a[name] = value, _a); } }; Object.defineProperty(prototype, name, attributes); }; for (var name in propertyTypes) { _loop_2(name); } } function makeKey(registeredKeys, prefix) { if (prefix === void 0) { prefix = ""; } var index = 0; // eslint-disable-next-line no-constant-condition while (true) { var key = "infinitegrid_".concat(prefix).concat(index++); if (!(key in registeredKeys)) { return key; } } } function convertHTMLtoElement(html) { var dummy = document.createElement("div"); dummy.innerHTML = html; return toArray(dummy.children); } function convertInsertedItems(items, groupKey) { var insertedItems; if (isString(items)) { insertedItems = convertHTMLtoElement(items); } else { insertedItems = items; } return insertedItems.map(function (item) { var element; var html = ""; var key; if (isString(item)) { html = item; } else if ("parentNode" in item) { element = item; html = item.outerHTML; } else { // inserted is true when adding via a method. return __assign({ groupKey: groupKey, inserted: true }, item); } // inserted is true when adding via a method. return { key: key, groupKey: groupKey, html: html, element: element, inserted: true }; }); } function toArray(nodes) { var array = []; if (nodes) { var length = nodes.length; for (var i = 0; i < length; i++) { array.push(nodes[i]); } } return array; } function findIndex(arr, callback) { var length = arr.length; for (var i = 0; i < length; ++i) { if (callback(arr[i], i)) { return i; } } return -1; } function findLastIndex(arr, callback) { var length = arr.length; for (var i = length - 1; i >= 0; --i) { if (callback(arr[i], i)) { return i; } } return -1; } function getItemInfo(info) { var nextInfo = {}; for (var name in info) { if (name in ITEM_INFO_PROPERTIES) { nextInfo[name] = info[name]; } } return nextInfo; } function setPlaceholder(item, info) { for (var name in info) { var value = info[name]; if (isObject(value)) { item[name] = __assign(__assign({}, item[name]), value); } else { item[name] = info[name]; } } } function isFlatOutline(start, end) { return start.length === end.length && start.every(function (pos, i) { return end[i] === pos; }); } function range(length) { var arr = []; for (var i = 0; i < length; ++i) { arr.push(i); } return arr; } function flatGroups(groups) { return flat(groups.map(function (_a) { var grid = _a.grid; return grid.getItems(); })); } function filterVirtuals(items, includePlaceholders) { if (includePlaceholders) { return __spreadArray([], items, true); } else { return items.filter(function (item) { return item.type !== exports.ITEM_TYPE.VIRTUAL; }); } } /** * Decorator that makes the method of InfiniteGrid available in the framework. * @ko 프레임워크에서 InfiniteGrid의 메소드를 사용할 수 있게 하는 데코레이터. * @private * @example * ```js * import { withInfiniteGridMethods } from "@egjs/infinitegrid"; * * class Grid extends React.Component<Partial<InfiniteGridProps & InfiniteGridOptions>> { * &#64;withInfiniteGridMethods * private grid: NativeGrid; * } * ``` */ var withInfiniteGridMethods = core.withClassMethods(INFINITEGRID_METHODS); var GroupManager = /*#__PURE__*/function (_super) { __extends(GroupManager, _super); function GroupManager(container, options) { var _this = _super.call(this, container, splitOptions(options)) || this; _this.groupItems = []; _this.groups = []; _this.itemKeys = {}; _this.groupKeys = {}; _this.startCursor = 0; _this.endCursor = 0; _this._placeholder = null; _this._loadingGrid = new LoadingGrid(container, { externalContainerManager: _this.containerManager, useFit: false, autoResize: false, renderOnPropertyChange: false, gap: _this.gap }); _this._mainGrid = _this._makeGrid(); return _this; } var __proto = GroupManager.prototype; Object.defineProperty(__proto, "gridOptions", { set: function (options) { var _a = splitGridOptions(options), gridOptions = _a.gridOptions, otherOptions = __rest(_a, ["gridOptions"]); var shouldRender = this._checkShouldRender(options); this.options.gridOptions = __assign(__assign({}, this.options.gridOptions), gridOptions); __spreadArray([this._mainGrid], this.groups.map(function (_a) { var grid = _a.grid; return grid; }), true).forEach(function (grid) { for (var name in options) { grid[name] = options[name]; } }); for (var name in otherOptions) { this[name] = otherOptions[name]; } this._loadingGrid.gap = this.gap; if (shouldRender) { this.scheduleRender(); } }, enumerable: false, configurable: true }); __proto.getItemByKey = function (key) { return this.itemKeys[key] || null; }; __proto.getGroupItems = function (includePlaceholders) { return filterVirtuals(this.groupItems, includePlaceholders); }; __proto.getVisibleItems = function (includePlaceholders) { return filterVirtuals(this.items, includePlaceholders); }; __proto.getRenderingItems = function () { if (this.hasPlaceholder()) { return this.items; } else { return this.items.filter(function (item) { return item.type !== exports.ITEM_TYPE.VIRTUAL; }); } }; __proto.getGroups = function (includePlaceholders) { return filterVirtuals(this.groups, includePlaceholders); }; __proto.hasVisibleVirtualGroups = function () { return this.getVisibleGroups(true).some(function (group) { return group.type === exports.GROUP_TYPE.VIRTUAL; }); }; __proto.hasPlaceholder = function () { return !!this._placeholder; }; __proto.hasLoadingItem = function () { return !!this._getLoadingItem(); }; __proto.updateItems = function (items, options) { if (items === void 0) { items = this.groupItems; } return _super.prototype.updateItems.call(this, items, options); }; __proto.setPlaceholder = function (placeholder) { this._placeholder = placeholder; this._updatePlaceholder(); }; __proto.getLoadingType = function () { return this._loadingGrid.type; }; __proto.startLoading = function (type) { this._loadingGrid.type = type; this.items = this._getRenderingItems(); return true; }; __proto.waitEndLoading = function () { if (!this._loadingGrid.isWaitEnd && this._loadingGrid.type) { this._loadingGrid.isWaitEnd = true; return true; } return false; }; __proto.endLoading = function () { if (this._loadingGrid.isWaitEnd) { var prevType = this._loadingGrid.type; this._loadingGrid.type = ""; this._loadingGrid.endLoading(); this.items = this._getRenderingItems(); return !!prevType; } return false; }; __proto.setLoading = function (loading) { this._loadingGrid.setLoadingItem(loading); this.items = this._getRenderingItems(); }; __proto.getVisibleGroups = function (includePlaceholders) { var groups = this.groups.slice(this.startCursor, this.endCursor + 1); return filterVirtuals(groups, includePlaceholders); }; __proto.getComputedOutlineLength = function (items) { if (items === void 0) { items = this.items; } return this._mainGrid.getComputedOutlineLength(items); }; __proto.getComputedOutlineSize = function (items) { if (items === void 0) { items = this.items; } return this._mainGrid.getComputedOutlineSize(items); }; __proto.applyGrid = function (items, direction, outline) { var _this = this; var renderingGroups = this.groups.slice(); if (!renderingGroups.length) { return { start: [], end: [] }; } var loadingGrid = this._loadingGrid; if (loadingGrid.getLoadingItem()) { if (loadingGrid.type === "start") { renderingGroups.unshift(this._getLoadingGroup()); } else if (loadingGrid.type === "end") { renderingGroups.push(this._getLoadingGroup()); } } var groups = renderingGroups.slice(); var nextOutline = outline; if (direction === "start") { groups.reverse(); } var appliedItemChecker = this.options.appliedItemChecker; var groupItems = this.groupItems; var outlineLength = this.getComputedOutlineLength(groupItems); var outlineSize = this.getComputedOutlineSize(groupItems); var itemRenderer = this.itemRenderer; var passedItems = []; groups.forEach(function (group) { var _a, _b; var grid = group.grid; var gridItems = grid.getItems(); var isVirtual = group.type === exports.GROUP_TYPE.VIRTUAL && !gridItems[0]; passedItems = direction === "end" ? __spreadArray(__spreadArray([], passedItems, true), gridItems, true) : __spreadArray(__spreadArray([], gridItems, true), passedItems, true); grid.outlineLength = outlineLength; grid.outlineSize = outlineSize; var appliedItems = passedItems.filter(function (item) { if (item.mountState === Grid.MOUNT_STATE.UNCHECKED || !item.rect.width) { itemRenderer.updateItem(item, true); } return item.orgRect.width && item.rect.width || appliedItemChecker(item, grid); }); var gridOutlines; if (isVirtual) { gridOutlines = _this._applyVirtualGrid(grid, direction, nextOutline); } else if (appliedItems.length) { gridOutlines = grid.applyGrid(appliedItems, direction, nextOutline); } else { gridOutlines = { start: __spreadArray([], nextOutline, true), end: __spreadArray([], nextOutline, true) }; } grid.setOutlines(gridOutlines); nextOutline = gridOutlines.passed || gridOutlines[direction]; passedItems = (_b = (_a = gridOutlines.passedItems) === null || _a === void 0 ? void 0 : _a.map(function (index) { return passedItems[index]; })) !== null && _b !== void 0 ? _b : []; }); return { start: renderingGroups[0].grid.getOutlines().start, end: renderingGroups[renderingGroups.length - 1].grid.getOutlines().end }; }; __proto.syncItems = function (nextItemInfos) { var _this = this; var prevItemKeys = this.itemKeys; this.itemKeys = {}; var nextItems = this._syncItemInfos(nextItemInfos.map(function (info) { return getItemInfo(info); }), prevItemKeys); var prevGroupKeys = this.groupKeys; var nextManagerGroups = categorize(nextItems); var startVirtualGroups = this._splitVirtualGroups("start", nextManagerGroups); var endVirtualGroups = this._splitVirtualGroups("end", nextManagerGroups); nextManagerGroups = __spreadArray(__spreadArray(__spreadArray([], startVirtualGroups, true), this._mergeVirtualGroups(nextManagerGroups), true), endVirtualGroups, true); var nextGroups = nextManagerGroups.map(function (_a) { var _b, _c; var groupKey = _a.groupKey, items = _a.items; var isVirtual = !items[0] || items[0].type === exports.ITEM_TYPE.VIRTUAL; var grid = (_c = (_b = prevGroupKeys[groupKey]) === null || _b === void 0 ? void 0 : _b.grid) !== null && _c !== void 0 ? _c : _this._makeGrid(); var gridItems = isVirtual ? items : items.filter(function (_a) { var type = _a.type; return type === exports.ITEM_TYPE.NORMAL; }); grid.setItems(gridItems); return { type: isVirtual ? exports.GROUP_TYPE.VIRTUAL : exports.GROUP_TYPE.NORMAL, groupKey: groupKey, grid: grid, items: gridItems, renderItems: items }; }); this._registerGroups(nextGroups); }; __proto.renderItems = function (options) { if (options === void 0) { options = {}; } if (options.useResize) { this.groupItems.forEach(function (item) { item.updateState = Grid.UPDATE_STATE.NEED_UPDATE; }); var loadingItem = this._getLoadingItem(); if (loadingItem) { loadingItem.updateState = Grid.UPDATE_STATE.NEED_UPDATE; } } return _super.prototype.renderItems.call(this, options); }; __proto.setCursors = function (startCursor, endCursor) { this.startCursor = startCursor; this.endCursor = endCursor; this.items = this._getRenderingItems(); }; __proto.getStartCursor = function () { return this.startCursor; }; __proto.getEndCursor = function () { return this.endCursor; }; __proto.getGroupStatus = function (type, includePlaceholders) { var orgStartCursor = this.startCursor; var orgEndCursor = this.endCursor; var orgGroups = this.groups; var startGroup = orgGroups[orgStartCursor]; var endGroup = orgGroups[orgEndCursor]; var startCursor = orgStartCursor; var endCursor = orgEndCursor; var isMinimizeItems = type === exports.STATUS_TYPE.MINIMIZE_INVISIBLE_ITEMS; var isMinimizeGroups = type === exports.STATUS_TYPE.MINIMIZE_INVISIBLE_GROUPS; var groups; if (type === exports.STATUS_TYPE.REMOVE_INVISIBLE_GROUPS) { groups = this.getVisibleGroups(includePlaceholders); endCursor = groups.length - 1; startCursor = 0; } else { groups = this.getGroups(includePlaceholders); if (!includePlaceholders) { startCursor = -1; endCursor = -1; for (var orgIndex = orgStartCursor; orgIndex <= orgEndCursor; ++orgIndex) { var orgGroup = orgGroups[orgIndex]; if (orgGroup && orgGroup.type !== exports.GROUP_TYPE.VIRTUAL) { startCursor = groups.indexOf(orgGroup); break; } } for (var orgIndex = orgEndCursor; orgIndex >= orgStartCursor; --orgIndex) { var orgGroup = orgGroups[orgIndex]; if (orgGroup && orgGroup.type !== exports.GROUP_TYPE.VIRTUAL) { endCursor = groups.lastIndexOf(orgGroup); break; } } } } var groupStatus = groups.map(function (_a, i) { var grid = _a.grid, groupKey = _a.groupKey; var isOutsideCursor = i < startCursor || endCursor < i; var isVirtualItems = isMinimizeItems && isOutsideCursor; var isVirtualGroup = isMinimizeGroups && isOutsideCursor; var gridItems = grid.getItems(); var items = isVirtualGroup ? [] : gridItems.map(function (item) { return isVirtualItems ? item.getVirtualStatus() : item.getMinimizedStatus(); }); return { type: isVirtualGroup || isVirtualItems ? exports.GROUP_TYPE.VIRTUAL : exports.GROUP_TYPE.NORMAL, groupKey: groupKey, outlines: grid.getOutlines(), items: items }; }); var totalItems = this.getGroupItems(); var itemStartCursor = totalItems.indexOf(startGroup === null || startGroup === void 0 ? void 0 : startGroup.items[0]); var itemEndCursor = totalItems.indexOf(endGroup === null || endGroup === void 0 ? void 0 : endGroup.items.slice().reverse()[0]); return { cursors: [startCursor, endCursor], orgCursors: [orgStartCursor, orgEndCursor], itemCursors: [itemStartCursor, itemEndCursor], startGroupKey: startGroup === null || startGroup === void 0 ? void 0 : startGroup.groupKey, endGroupKey: endGroup === null || endGroup === void 0 ? void 0 : endGroup.groupKey, groups: groupStatus, outlines: this.outlines }; }; __proto.fitOutlines = function (useFit) { if (useFit === void 0) { useFit = this.useFit; } var groups = this.groups; if (!groups[0]) { return; } var outlines = this.outlines; var startOutline = outlines.start; var outlineOffset = startOutline.length ? Math.min.apply(Math, startOutline) : 0; // If the outline is less than 0, a fit occurs forcibly. if (!useFit && outlineOffset > 0) { return; } groups.forEach(function (_a) { var grid = _a.grid; var _b = grid.getOutlines(), start = _b.start, end = _b.end; grid.setOutlines({ start: start.map(function (point) { return point - outlineOffset; }), end: end.map(function (point) { return point - outlineOffset; }) }); }); this.groupItems.forEach(function (item) { var contentPos = item.cssContentPos; if (!isNumber(contentPos)) { return; } item.cssContentPos = contentPos - outlineOffset; }); }; __proto.setGroupStatus = function (status) { var _this = this; this.itemKeys = {}; this.groupItems = []; this.items = []; var prevGroupKeys = this.groupKeys; var nextGroups = status.groups.map(function (_a) { var _b, _c; var type = _a.type, groupKey = _a.groupKey, items = _a.items, outlines = _a.outlines; var nextItems = _this._syncItemInfos(items); var grid = (_c = (_b = prevGroupKeys[groupKey]) === null || _b === void 0 ? void 0 : _b.grid) !== null && _c !== void 0 ? _c : _this._makeGrid(); grid.setOutlines(outlines); grid.setItems(nextItems); return { type: type, groupKey: groupKey, grid: grid, items: nextItems, renderItems: nextItems }; }); this.setOutlines(status.outlines); this._registerGroups(nextGroups); this._updatePlaceholder(); this.setCursors(status.cursors[0], status.cursors[1]); }; __proto.appendPlaceholders = function (items, groupKey) { return this.insertPlaceholders("end", items, groupKey); }; __proto.prependPlaceholders = function (items, groupKey) { return this.insertPlaceholders("start", items, groupKey); }; __proto.removePlaceholders = function (type) { var groups = this.groups; var length = groups.length; if (type === "start") { var index = findIndex(groups, function (group) { return group.type === exports.GROUP_TYPE.NORMAL; }); groups.splice(0, index); } else if (type === "end") { var index = findLastIndex(groups, function (group) { return group.type === exports.GROUP_TYPE.NORMAL; }); groups.splice(index + 1, length - index - 1); } else { var groupKey_1 = type.groupKey; var index = findIndex(groups, function (group) { return group.groupKey === groupKey_1; }); if (index > -1) { groups.splice(index, 1); } } this.syncItems(flatGroups(this.getGroups())); }; __proto.insertPlaceholders = function (direction, items, groupKey) { var _a, _b; if (groupKey === void 0) { groupKey = makeKey(this.groupKeys, "virtual_"); } var infos = []; if (isNumber(items)) { infos = range(items).map(function () { return { type: exports.ITEM_TYPE.VIRTUAL, groupKey: groupKey }; }); } else if (Array.isArray(items)) { infos = items.map(function (status) { return __assign(__assign({ groupKey: groupKey }, status), { type: exports.ITEM_TYPE.VIRTUAL }); }); } var grid = this._makeGrid(); var nextItems = this._syncItemInfos(infos, this.itemKeys); this._updatePlaceholder(nextItems); grid.setItems(nextItems); var group = { type: exports.GROUP_TYPE.VIRTUAL, groupKey: groupKey, grid: grid, items: nextItems, renderItems: nextItems }; this.groupKeys[groupKey] = group; if (direction === "end") { this.groups.push(group); (_a = this.groupItems).push.apply(_a, nextItems); } else { this.groups.splice(0, 0, group); (_b = this.groupItems).splice.apply(_b, __spreadArray([0, 0], nextItems, false)); if (this.startCursor > -1) { ++this.startCursor; ++this.endCursor; } } return { group: group, items: nextItems }; }; __proto.shouldRerenderItems = function () { var isRerender = false; this.getVisibleGroups().forEach(function (group) { var items = group.items; if (items.length === group.renderItems.length || items.every(function (item) { return item.mountState === Grid.MOUNT_STATE.UNCHECKED; })) { return; } isRerender = true; group.renderItems = __spreadArray([], items, true); }); if (isRerender) { this.items = this._getRenderingItems(); } return isRerender; }; // protected checkReady(options: RenderOptions = {}) { // const items = this.items; // const updated = items.filter((item) => item.element?.parentNode && item.updateState !== UPDATE_STATE.UPDATED); // const mounted = items.filter((item) => item.element?.parentNode && item.mountState !== MOUNT_STATE.MOUNTED); // if (updated.length && updated.every((item) => item.type != ITEM_TYPE.NORMAL)) { // this._updateItems(updated); // this.readyItems(mounted, updated, options); // } else { // super.checkReady(options); // } // } __proto._updateItems = function (items) { this.itemRenderer.updateEqualSizeItems(items, this.groupItems); }; __proto._getGroupItems = function () { return flatGroups(this.getGroups(true)); }; __proto._getRenderingItems = function () { var items = flat(this.getVisibleGroups(true).map(function (item) { return item.renderItems; })); var loadingGrid = this._loadingGrid; var loadingItem = loadingGrid.getLoadingItem(); if (loadingItem) { if (loadingGrid.type === "end") { items.push(loadingItem); } else if (loadingGrid.type === "start") { items.unshift(loadingItem); } } return items; }; __proto._checkShouldRender = function (options) { var GridConstructor = this.options.gridConstructor; var prevOptions = this.gridOptions; var propertyTypes = GridConstructor.propertyTypes; for (var name in prevOptions) { if (!(name in options) && propertyTypes[name] === Grid.PROPERTY_TYPE.RENDER_PROPERTY) { return true; } } for (var name in options) { if (prevOptions[name] !== options[name] && propertyTypes[name] === Grid.PROPERTY_TYPE.RENDER_PROPERTY) { return true; } } return false; }; __proto._applyVirtualGrid = function (grid, direction, outline) { var startOutline = outline.length ? __spreadArray([], outline, true) : [0]; var prevOutlines = grid.getOutlines(); var prevOutline = prevOutlines[direction === "end" ? "start" : "end"]; if (prevOutline.length !== startOutline.length || prevOutline.some(function (value, i) { return value !== startOutline[i]; })) { return { start: __spreadArray([], startOutline, true), end: __spreadArray([], startOutline, true) }; } return prevOutlines; }; __proto._syncItemInfos = function (nextItemInfos, prevItemKeys) { if (prevItemKeys === void 0) { prevItemKeys = {}; } var horizontal = this.options.horizontal; var nextItemKeys = this.itemKeys; nextItemInfos.filter(function (info) { return info.key != null; }).forEach(function (info) { var key = info.key; var prevItem = prevItemKeys[key]; if (!prevItem) { nextItemKeys[key] = new InfiniteGridItem(horizontal, __assign({}, info)); } else if (prevItem.type === exports.ITEM_TYPE.VIRTUAL && info.type !== exports.ITEM_TYPE.VIRTUAL) { nextItemKeys[key] = new InfiniteGridItem(horizontal, __assign({ orgRect: prevItem.orgRect, rect: prevItem.rect }, info)); } else { if (info.data) { prevItem.data = info.data; } if (info.groupKey != null) { prevItem.groupKey = info.groupKey; } if (info.element) { prevItem.element = info.element; } nextItemKeys[key] = prevItem; } }); var nextItems = nextItemInfos.map(function (info) { var key = info.key; if (info.key == null) { key = makeKey(nextItemKeys, info.type === exports.ITEM_TYPE.VIRTUAL ? "virtual_" : ""); } var item = nextItemKeys[key]; if (!item) { var prevItem = prevItemKeys[key]; if (prevItem) { item = prevItem; if (info.data) { item.data = info.data; } if (info.element) { item.element = info.element; } } else { item = new InfiniteGridItem(horizontal, __assign(__assign({}, info), { key: key })); } nextItemKeys[key] = item; } return item; }); return nextItems; }; __proto._registerGroups = function (groups) { var nextGroupKeys = {}; groups.forEach(function (group) { nextGroupKeys[group.groupKey] = group; }); this.groups = groups; this.groupKeys = nextGroupKeys; this.groupItems = this._getGroupItems(); }; __proto._splitVirtualGroups = function (direction, nextGroups) { var groups = splitVirtualGroups(this.groups, direction, nextGroups); var itemKeys = this.itemKeys; groups.forEach(function (_a) { var renderItems = _a.renderItems; renderItems.forEach(function (item) { itemKeys[item.key] = item; }); }); return groups; }; __proto._mergeVirtualGroups = function (groups) { var itemKeys = this.itemKeys; var groupKeys = this.groupKeys; groups.forEach(function (group) { var prevGroup = groupKeys[group.groupKey]; if (!prevGroup) { return; } var items = group.items; if (items.every(function (item) { return item.mountState === Grid.MOUNT_STATE.UNCHECKED; })) { prevGroup.renderItems.forEach(function (item) { if (item.type === exports.ITEM_TYPE.VIRTUAL && !itemKeys[item.key]) { items.push(item); itemKeys[item.key] = item; } }); } }); return groups; }; __proto._updatePlaceholder = function (items) { if (items === void 0) { items = this.groupItems; } var placeholder = this._placeholder; if (!placeholder) { return; } items.filter(function (item) { return item.type === exports.ITEM_TYPE.VIRTUAL; }).forEach(function (item) { setPlaceholder(item, placeholder); }); }; __proto._makeGrid = function () { var GridConstructor = this.options.gridConstructor; var gridOptions = this.gridOptions; var container = this.containerElement; return new GridConstructor(container, __assign(__assign({}, gridOptions), { useFit: false, autoResize: false, useResizeObserver: false, observeChildren: false, renderOnPropertyChange: false, externalContainerManager: this.containerManager, externalItemRenderer: this.itemRenderer })); }; __proto._getLoadingGroup = function () { var loadingGrid = this._loadingGrid; var items = loadingGrid.getItems(); return { groupKey: LOADING_GROUP_KEY, type: exports.GROUP_TYPE.NORMAL, grid: loadingGrid, items: items, renderItems: items }; }; __proto._getLoadingItem = function () { return this._loadingGrid.getLoadingItem(); }; GroupManager.defaultOptions = __assign(__assign({}, Grid.defaultOptions), { appliedItemChecker: function () { return false; }, gridConstructor: null, gridOptions: {} }); GroupManager.propertyTypes = __assign(__assign({}, Grid.propertyTypes), { gridConstructor: Grid.PROPERTY_TYPE.PROPERTY, gridOptions: Grid.PROPERTY_TYPE.PROPERTY }); GroupManager = __decorate([Grid.GetterSetter], GroupManager); return GroupManager; }(Grid); // 파트의 가운데 부분을 중심으로 스크롤 하기 위한 함수 function getCenterPosByParts(parts) { if (!parts.length) { return 0; } var minPos = Infinity; var maxPos = -Infinity; parts.forEach(function (part) { minPos = Math.min(minPos, part.pos); maxPos = Math.max(maxPos, part.pos + part.size); }, 0); return (minPos + maxPos) / 2; } var Infinite = /*#__PURE__*/function (_super) { __extends(Infinite, _super); function Infinite(options) { var _this = _super.call(this) || this; _this.startCursor = -1; _this.endCursor = -1; _this.size = 0; _this.items = []; _this.itemKeys = {}; _this.options = __assign({ threshold: 0, useRecycle: true, defaultDirection: "end", isReachStart: false, isReachEnd: false }, options); return _this; } var __proto = Infinite.prototype; Object.defineProperty(__proto, "isReachStart", { set: function (value) { this.options.isReachStart = value; }, enumerable: false, configurable: true }); Object.defineProperty(__proto, "isReachEnd", { set: function (value) { this.options.isReachEnd = value; }, enumerable: false, configurable: true }); __proto.scroll = function (scrollPos) { var _a, _b; var prevStartCursor = this.startCursor; var prevEndCursor = this.endCursor; var items = this.items; var length = items.length; var size = this.size; var _c = this.options, defaultDirection = _c.defaultDirection, threshold = _c.threshold, useRecycle = _c.useRecycle, isReachEnd = _c.isReachEnd, isReachStart = _c.isReachStart; var isDirectionEnd = defaultDirection === "end"; if (!length) { if (isReachStart && isReachEnd) { return; } var requestType = ""; if (!isReachEnd && isDirectionEnd) { // 1st order requestType = "requestAppend"; } else if (!isReachStart && !isDirectionEnd) { // 2nd order requestType = "requestPrepend"; } else if (!isReachEnd && isReachStart) { // 3rd order requestType = "requestAppend"; } else if (isReachEnd && !isReachStart) { // 4th order requestType = "requestPrepend"; } if (!requestType) { return; } this.trigger(requestType, { key: undefined, isVirtual: false }); return; } else if (prevStartCursor === -1 || prevEndCursor === -1) { var nextCursor = isDirectionEnd ? 0 : length - 1; this.trigger("change", { prevStartCursor: prevStartCursor, prevEndCursor: prevEndCursor, nextStartCursor: nextCursor, nextEndCursor: nextCursor }); return; } var endScrollPos = scrollPos + size; var startEdgePos = Math.max.apply(Math, items[prevStartCursor].startOutline); var endEdgePos = Math.min.apply(Math, items[prevEndCursor].endOutline); var visibles = items.map(function (item) { var startOutline = item.startOutline, endOutline = item.endOutline; if (!startOutline.length || !endOutline.length || isFlatOutline(startOutline, endOutline)) { return false; } var startPos = Math.min.apply(Math, startOutline); var endPos = Math.max.apply(Math, endOutline); if (startPos - threshold <= endScrollPos && scrollPos <= endPos + threshold) { return true; } return false; }); var hasStartItems = 0 < prevStartCursor; var hasEndItems = prevEndCursor < length - 1; var isStart = scrollPos <= startEdgePos + threshold; var isEnd = endScrollPos >= endEdgePos - threshold; var nextStartCursor = visibles.indexOf(true); var nextEndCursor = visibles.lastIndexOf(true); if (nextStartCursor === -1) {