PageSourceSearch

https://www.ignotapothon.com/Ext/Resources?a=CLe5H_Yo_xKcOYsdCuvob…gTqwQ77rg34PTxXzUEMKBj3ud7pL3iaySupDQrEL0bi

js ignotapothon.com collected 2026-09-28 17:14:43 UTC 8,740 bytes, 264 lines download raw bytes

1WS.Namespace.Create('NovAxis.VirtualCollection', (function () {
2    var PIXEL = "px";
3    var PERCENT = "%";
4
5    // Constructor
6    var _class = function (htmlElement, options) {
7        if (!htmlElement)
8            throw _error('First argument type must be HTMLElement');
9        if (typeof options !== 'object')
10            throw _error('Options argument is missing or invalid. Received ' + props);
11        if (typeof options.cellRenderer !== 'function')
12            throw _error('Option "cellRenderer" must be a function.');
13
14        this._scrollUpdateDeltaTime = 10;
15        this._lastUpdateTime = 0;
16        this._renderedCellCache = [];
17        this._renderedEmptyCell = null;
18        this._layout = {
19            cellHeight: 0,
20            cellWidth: 0,
21            width: 0,
22            height: 0,
23            cellWidthPercent: 0
24        };
25
26        this.container = $(htmlElement);
27        this.scrollable = $('<div class="scrollable"></div>');
28        this.options = {
29            cellRenderer: null,
30            noCellRenderer: null,
31            cellCount: 0,
32            useCache: true,
33            scrollablePadding: 0,
34            rowOverload: 1
35        };
36
37        Init.call(this, options);
38    };
39
40    // Private methods
41
42    var Init = function (options) {
43        var me = this;
44
45        var container = this.container;
46
47        container.append(this.scrollable);
48        container.on('scroll', OnContainerScroll.bind(this));
49
50        timeout = false;
51        delay = 300;
52        $(window).on("resize orientationchange", function () {
53            clearTimeout(timeout);
54            timeout = setTimeout(OnWindowResize.bind(me), delay);
55        });
56
57        this.UpdateOptions(options);
58    };
59
60    /**
61     * Renders a specified cell index using the current visible row and column index.
62     */
63    var RenderCell = function (index, rowIndex, colIndex, noCache) {
64        var opt = this.options;
65        var style = GetCellPositionStyle.call(this, index, rowIndex, colIndex);
66
67        if (index < 0) {
68            cell = CreateCell(index, style, opt.noCellRenderer);
69            this._renderedEmptyCell = cell;
70            return cell;
71        } else {
72            var cell = noCache ? null : this._renderedCellCache[index];
73            if (!cell) {
74                cell = CreateCell(index, style, opt.cellRenderer);
75                if (!noCache) {
76                    this._renderedCellCache[index] = cell;
77                }
78            }
79            return cell;
80        }
81    };
82
83    var GetCellPositionStyle = function (index, rowIndex, colIndex) {
84        var layout = this._layout;
85        var cellWidthPercent = layout.cellWidthPercent;
86        var cellHeight = layout.cellHeight;
87        return {
88            position: 'absolute',
89            top: (rowIndex * cellHeight) + PIXEL,
90            left: (colIndex * cellWidthPercent) + PERCENT
91        };
92    };
93
94    /**
95     * Creates a new cell element with required style.
96     */
97    var CreateCell = function (index, style, cellRenderer) {
98        var cell = $('<div></div>');
99        UpdateStyle(cell, style);
100        return cellRenderer(index, cell, style);
101    };
102
103    /**
104     * Removes all "out-of-range" elements from DOM.
105     */
106    var DetachElements = function (indexStart, indexEnd) {
107        var scrollable = this.scrollable;
108        var cells = this._renderedCellCache;
109        var length = cells.length;
110        for (var i = 0; i < length; i++) {
111            if (i < indexStart || i > indexEnd) {
112                var element = cells[i];
113                if (element) {
114                    element.detach();
115                    if (!this.options.useCache) {
116                        this._renderedCellCache[i] = void 0;
117                    }
118                }
119            }
120        }
121    };
122
123    var GetScrollableHeight = function () {
124        var layout = this._layout;
125        return layout.cellHeight * Math.ceil(this.options.cellCount / Math.floor(layout.width / layout.cellWidth));
126    }
127
128    var UpdateStyle = function (element, newStyle) {
129        element.css(newStyle);
130    };
131
132    var OnContainerScroll = function (event) {
133        var time = event.timeStamp;
134        if ((time - this._lastUpdateTime) > this._scrollUpdateDeltaTime) {
135            this.Render();
136        }
137    };
138
139    var OnWindowResize = function (event) {
140        this.Layout();
141    };
142
143    var _error = function (message) {
144        return new Error('VirtualCollection: ' + message);
145    };
146
147    var _assign = function (target, source) {
148        for (var key in source) {
149            target[key] = source[key];
150        }
151    };
152
153    // Public methods
154
155    (function (methods) {
156
157        methods.Layout = function () {
158            var container = this.container;
159            var ghostCell = this.options.cellCount > 0 ? RenderCell.call(this, 0, 0, 0, true) : $('<div></div>');
160            var layout = this._layout;
161
162            ghostCell.css('visibility', 'hidden');
163
164            this.ClearCache();
165            this.scrollable.append(ghostCell);
166
167            var width = this.scrollable.innerWidth()
168            var cellWidth = ghostCell.innerWidth();
169
170            _assign(layout, {
171                width: width,
172                height: container.innerHeight(),
173                cellWidth: cellWidth,
174                cellHeight: ghostCell.innerHeight(),
175                cellWidthPercent: cellWidth * 100 / width
176            });
177
178            var scrollHeight = GetScrollableHeight.call(this);
179
180            UpdateStyle(this.scrollable, {
181                position: 'relative',
182                overflow: 'hidden',
183                width: '100%',
184                height: scrollHeight + PIXEL
185            });
186
187            container.scrollTop(Math.min(container.scrollTop(), scrollHeight - layout.height));
188
189            ghostCell.detach();
190
191            this.Render();
192
193            return this;
194        };
195
196        methods.Render = function () {
197            var opt = this.options;
198            var layout = this._layout;
199            var scrollable = this.scrollable;
200            var rowIndexStart = Math.floor(this.GetScrollTop() / layout.cellHeight);
201            var rowIndexEnd = rowIndexStart + (layout.height / layout.cellHeight) + opt.rowOverload;
202            var columnCount = Math.floor(layout.width / layout.cellWidth);
203            var columnIndexStart = Math.floor(this.GetScrollLeft() / layout.cellWidth);
204            var columnIndexEnd = columnIndexStart + columnCount;
205            var index = rowIndexStart * columnCount;
206
207            var renderedCellCount = Math.min(opt.cellCount, (rowIndexEnd - rowIndexStart) * (columnIndexEnd - columnIndexStart));
208
209            if (renderedCellCount < 1 && typeof opt.noCellRenderer === 'function') {
210                scrollable.empty();
211                scrollable.append(RenderCell.call(this, -1, 0, 0));
212                scrollable.css({ height: 'auto' });
213                return;
214            }
215
216            DetachElements.call(this, index, index + renderedCellCount - 1);
217            scrollable.css({ height: GetScrollableHeight.call(this) + PIXEL });
218
219            for (var i = rowIndexStart; i < rowIndexEnd; i++) {
220                for (var j = columnIndexStart; j < columnIndexEnd; j++) {
221                    if (index < opt.cellCount) {
222                        scrollable.append(RenderCell.call(this, index, i, j));
223                    }
224                    index++;
225                }
226            }
227            return this;
228        };
229
230        methods.UpdateOptions = function (options) {
231            if (options) {
232                _assign(this.options, options);
233            }
234            this.Layout();
235        };
236
237        methods.ClearCache = function () {
238            var length = this._renderedCellCache.length;
239            var cache = this._renderedCellCache;
240            var scrollable = this.scrollable;
241            for (var i = 0; i < length; i++) {
242                var element = cache[i];
243                if (element) element.detach();
244            }
245            if (this._renderedEmptyCell) this._renderedEmptyCell.detach();
246            this._renderedCellCache = [];
247        };
248
249        methods.ScrollTo = function (scrollTop) {
250            this.container.scrollTop(scrollTop);
251        };
252
253        methods.GetScrollTop = function () {
254            return this.container.scrollTop();
255        };
256
257        methods.GetScrollLeft = function () {
258            return this.container.scrollLeft();
259        };
260
261    })(_class.prototype);
262
263    return _class;
264})());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.