PageSourceSearch

https://vesti-perm.ru/_content/Microsoft.FluentUI.AspNetCore.Compo…/FluentDataGrid.srpwfo1per.razor.js

js vesti-perm.ru collected 2026-09-29 11:20:20 UTC 19,420 bytes, 515 lines download raw bytes

1let grids = [];
2
3export function init(gridElement, autoFocus) {
4    if (gridElement === undefined || gridElement === null) {
5        return;
6    };
7
8    const controller = new AbortController();
9    const { signal } = controller;
10
11    enableColumnResizing(gridElement, true, signal);
12
13    let start = gridElement.querySelector('td:first-child');
14
15    if (autoFocus) {
16        start.focus();
17    }
18
19    const bodyClickHandler = event => {
20        const columnOptionsElement = gridElement?.querySelector('.col-options');
21        if (columnOptionsElement && event.composedPath().indexOf(columnOptionsElement) < 0) {
22            gridElement.dispatchEvent(new CustomEvent('closecolumnoptions', { bubbles: true }));
23        }
24        const columnResizeElement = gridElement?.querySelector('.col-resize');
25        if (columnResizeElement && event.composedPath().indexOf(columnResizeElement) < 0) {
26            gridElement.dispatchEvent(new CustomEvent('closecolumnresize', { bubbles: true }));
27        }
28    };
29    const bodyKeyDownHandler = event => {
30        if (event.key === "Escape") {
31            const columnOptionsElement = gridElement?.querySelector('.col-options');
32            if (columnOptionsElement && columnOptionsElement.contains(event.target)) {
33                gridElement.dispatchEvent(new CustomEvent('closecolumnoptions', { bubbles: true }));
34                gridElement.focus();
35            }
36            const columnResizeElement = gridElement?.querySelector('.col-resize');
37            if (columnResizeElement) {
38                gridElement.dispatchEvent(new CustomEvent('closecolumnresize', { bubbles: true }));
39                gridElement.focus();
40            }
41        }
42    };
43    const keyboardNavigation = (sibling) => {
44        if (sibling !== null) {
45            start.focus();
46            sibling.focus();
47            start = sibling;
48        }
49    }
50    const keyDownHandler = event => {
51        const columnOptionsElement = gridElement?.querySelector('.col-options');
52        if (columnOptionsElement && columnOptionsElement.contains(event.target)) {
53            if (event.key === "ArrowRight" || event.key === "ArrowLeft" || event.key === "ArrowDown" || event.key === "ArrowUp") {
54                event.stopPropagation();
55                return;
56            }
57        }
58
59        const columnResizeElement = gridElement?.querySelector('.col-resize');
60        if (columnResizeElement && columnResizeElement.contains(event.target)) {
61            if (event.key === "ArrowRight" || event.key === "ArrowLeft" || event.key === "ArrowDown" || event.key === "ArrowUp") {
62                event.stopPropagation();
63                return;
64            }
65        }
66
67        if (document.activeElement.tagName.toLowerCase() != 'table' && document.activeElement.tagName.toLowerCase() != 'td' && document.activeElement.tagName.toLowerCase() != 'th') {
68            return;
69        }
70
71        // check if start is a child of gridElement
72        if (start !== null && (gridElement.contains(start) || gridElement === start) && document.activeElement === start && document.activeElement.tagName.toLowerCase() !== 'fluent-text-field' && document.activeElement.tagName.toLowerCase() !== 'fluent-menu-item') {
73            const idx = start.cellIndex;
74            const isRTL = getComputedStyle(gridElement).direction === 'rtl';
75
76            if (event.key === "ArrowUp") {
77                // up arrow
78                const previousRow = start.parentElement.previousElementSibling;
79                if (previousRow !== null) {
80                    event.preventDefault();
81                    const previousSibling = previousRow.cells[idx];
82                    keyboardNavigation(previousSibling);
83                }
84            } else if (event.key === "ArrowDown") {
85                // down arrow
86                const nextRow = start.parentElement.nextElementSibling;
87                if (nextRow !== null) {
88                    event.preventDefault();
89                    const nextSibling = nextRow.cells[idx];
90                    keyboardNavigation(nextSibling);
91                }
92            } else if (event.key === "ArrowLeft") {
93                // left arrow
94                event.preventDefault();
95                const previousSibling = isRTL ? start.nextElementSibling : start.previousElementSibling;
96                keyboardNavigation(previousSibling);
97                event.stopPropagation();
98            } else if (event.key === "ArrowRight") {
99                // right arrow
100                event.preventDefault();
101                const nextsibling = isRTL ? start.previousElementSibling : start.nextElementSibling;
102                keyboardNavigation(nextsibling);
103                event.stopPropagation();
104            }
105        }
106        else {
107            start = document.activeElement;
108        }
109
110    };
111
112    const cells = gridElement.querySelectorAll('[role="gridcell"]');
113    cells.forEach((cell) => {
114        cell.columnDefinition = {
115            columnDataKey: "",
116            cellInternalFocusQueue: true,
117            cellFocusTargetCallback: (cell) => {
118                return cell.children[0];
119            }
120        }
121        cell.addEventListener(
122            "keydown",
123            (event) => {
124                if (event.target.role !== "gridcell" && (event.key === "ArrowRight" || event.key === "ArrowLeft")) {
125                    event.stopPropagation();
126                }
127            },
128            { signal }
129        );
130    });
131
132    document.body.addEventListener('click', bodyClickHandler, { signal });
133    document.body.addEventListener('mousedown', bodyClickHandler, { signal }); // Otherwise it seems strange that it doesn't go away until you release the mouse button
134    document.body.addEventListener('keydown', bodyKeyDownHandler, { signal });
135    gridElement.addEventListener('keydown', keyDownHandler, { signal });
136
137    return {
138        stop: () => {
139            controller.abort();
140
141            const index = grids.findIndex(grid => grid.id === gridElement.id);
142            if (index > -1) {
143                const grid = grids[index];
144                if (grid.resizeController) {
145                    grid.resizeController.abort();
146                }
147                grids.splice(index, 1);
148            }
149        }
150    };
151}
152
153export function checkColumnPopupPosition(gridElement, selector) {
154    const colPopup = gridElement.querySelector(selector);
155    if (colPopup) {
156        const gridRect = gridElement.getBoundingClientRect();
157        const popupRect = colPopup.getBoundingClientRect();
158        const leftOverhang = Math.max(0, gridRect.left - popupRect.left);
159        const rightOverhang = Math.max(0, popupRect.right - gridRect.right);
160        if (leftOverhang || rightOverhang) {
161            const applyOffset = leftOverhang && rightOverhang ? (leftOverhang - rightOverhang) / 2 : (leftOverhang - rightOverhang);
162            colPopup.style.transform = `translateX(${applyOffset}px)`;
163        }
164
165        colPopup.style.visibility = 'visible';
166        colPopup.scrollIntoViewIfNeeded();
167
168        const autoFocusElem = colPopup.querySelector('[autofocus]');
169        if (autoFocusElem) {
170            autoFocusElem.focus();
171        }
172    }
173}
174
175export function enableColumnResizing(gridElement, resizeColumnOnAllRows = true, signal = null) {
176    const columns = [];
177    const headers = gridElement.querySelectorAll('.column-header.resizable');
178
179    if (headers.length === 0) {
180        return;
181    }
182
183    const id = gridElement.id;
184    let grid = grids.find(g => g.id === id);
185
186    if (grid?.resizeController) {
187        grid.resizeController.abort();
188    }
189
190    const localController = signal ? null : new AbortController();
191    const effectiveSignal = signal ?? localController.signal;
192
193    const isGrid = gridElement.classList.contains('grid')
194
195    let tableHeight = gridElement.offsetHeight;
196    // rows have not been loaded yet, so we need to calculate the height
197    if (tableHeight < 70) {
198        // by getting the aria rowcount attribute
199        const rowCount = gridElement.getAttribute('aria-rowcount');
200        if (rowCount) {
201            const rowHeight = gridElement.querySelector('thead tr th').offsetHeight;
202            // and multiply by the itemsize (== height of the header cells)
203            tableHeight = rowCount * rowHeight;
204        }
205    }
206
207    // Determine the height based on the resizeColumnOnAllRows parameter
208    let resizeHandleHeight = tableHeight;
209    if (!resizeColumnOnAllRows) {
210        // Only use the header height when resizeColumnOnAllRows is false
211        // Use the first header's height if available
212        resizeHandleHeight = headers.length > 0 ? (headers[0].offsetHeight - 14) : 32; // fallback to 32px if no headers
213    }
214
215    headers.forEach((header) => {
216        columns.push({
217            header,
218            size: `${header.clientWidth}px`,
219        });
220
221        // remove any previously created divs
222        const resizedivs = header.querySelectorAll(".actual-resize-handle");
223        resizedivs.forEach(div => div.remove());
224
225        // Get the top of the first resize-handle
226        const resizeTop = header.querySelector('.resize-handle').offsetTop;
227
228        // add a new resize div
229        const div = createDiv(resizeHandleHeight, resizeTop);
230        header.appendChild(div);
231        setListeners(div, effectiveSignal);
232    });
233
234    let initialWidths;
235    if (gridElement.style.gridTemplateColumns) {
236        initialWidths = gridElement.style.gridTemplateColumns;
237    } else {
238        initialWidths = columns.map(({ size }) => size).join(' ');
239
240        if (isGrid) {
241            gridElement.style.gridTemplateColumns = initialWidths;
242        }
243    }
244
245    if (!grid) {
246        grids.push({
247            id,
248            columns,
249            initialWidths,
250            resizeController: signal ? undefined : localController,
251        });
252    } else {
253        const columnsChanged = grid.columns.length !== columns.length;
254        grid.columns = columns;
255        if (columnsChanged) {
256            grid.initialWidths = initialWidths;
257        }
258        grid.resizeController = signal ? undefined : localController;
259    }
260
261    function setListeners(div, signal) {
262        let pageX, curCol, curColWidth;
263
264        const moveHandler = (e) =>
265            requestAnimationFrame(() => {
266                gridElement.style.tableLayout = 'fixed';
267
268                if (curCol) {
269                    const isRTL = getComputedStyle(gridElement).direction === 'rtl';
270                    const diffX = isRTL ? pageX - e.pageX : e.pageX - pageX;
271                    const column = columns.find(({ header }) => header === curCol);
272
273                    column.size = parseInt(Math.max(parseInt(column.header.style.minWidth), curColWidth + diffX), 10) + 'px';
274
275                    columns.forEach((col) => {
276                        if (col.size.startsWith('minmax')) {
277                            col.size = parseInt(col.header.clientWidth, 10) + 'px';
278                        }
279                    });
280
281                    if (isGrid) {
282                        gridElement.style.gridTemplateColumns = columns
283                            .map(({ size }) => size)
284                            .join(' ');
285                    }
286                    else {
287                        curCol.style.width = column.size;
288                    }
289                }
290            });
291
292        const upHandler = function () {
293            gridElement.removeEventListener('pointermove', moveHandler);
294            gridElement.removeEventListener('pointerup', upHandler);
295
296            curCol = undefined;
297            curColWidth = undefined;
298            pageX = undefined;
299        };
300
301        div.addEventListener('pointerdown', function (e) {
302            curCol = e.target.parentElement;
303            pageX = e.pageX;
304
305            const padding = paddingDiff(curCol);
306
307            curColWidth = curCol.offsetWidth - padding;
308
309            gridElement.addEventListener('pointermove', moveHandler, { signal });
310            gridElement.addEventListener('pointerup', upHandler, { signal });
311        }, { signal });
312
313        div.addEventListener('pointerover', function (e) {
314            e.target.style.borderInlineEnd = 'var(--fluent-data-grid-resize-handle-width) solid var(--fluent-data-grid-resize-handle-color)';
315            e.target.previousElementSibling.style.visibility = 'hidden';
316        }, { signal });
317
318        div.addEventListener('pointerup', removeBorder, { signal });
319        div.addEventListener('pointercancel', removeBorder, { signal });
320        div.addEventListener('pointerleave', removeBorder, { signal });
321    }
322
323    function createDiv(height, top) {
324        const div = document.createElement('div');
325        div.className = "actual-resize-handle";
326        div.style.top = top + 'px';
327        div.style.position = 'absolute';
328        div.style.cursor = 'col-resize';
329        div.style.userSelect = 'none';
330        div.style.height = (height - 4) + 'px';
331        div.style.width = '6px';
332        div.style.opacity = 'var(--fluent-data-grid-header-opacity)'
333        div.style.insetInlineEnd = '0';
334
335        return div;
336    }
337
338    function paddingDiff(col) {
339        if (getStyleVal(col, 'box-sizing') === 'border-box') {
340            return 0;
341        }
342
343        const padLeft = getStyleVal(col, 'padding-left');
344        const padRight = getStyleVal(col, 'padding-right');
345        return parseInt(padLeft) + parseInt(padRight);
346    }
347
348    function getStyleVal(elm, css) {
349        return window.getComputedStyle(elm, null).getPropertyValue(css);
350    }
351
352    function removeBorder(e) {
353        e.target.style.borderInlineEnd = '';
354        e.target.previousElementSibling.style.visibility = 'visible';
355    }
356}
357
358
359
360export function resetColumnWidths(gridElement) {
361    const isGrid = gridElement.classList.contains('grid');
362    const grid = grids.find(({ id }) => id === gridElement.id);
363    if (!grid) {
364        return;
365    }
366
367    if (isGrid) {
368        gridElement.style.gridTemplateColumns = grid.initialWidths;
369
370        // Force browser to recalculate so we can get accurate computed widths
371        const resolvedWidths = window.getComputedStyle(gridElement).gridTemplateColumns.split(' ');
372
373        grid.columns.forEach((column, index) => {
374            column.size = resolvedWidths[index];
375        });
376    } else {
377        const columnsWidths = grid.initialWidths.split(' ');
378        grid.columns.forEach((column, index) => {
379            column.size = columnsWidths[index];
380            column.header.style.width = column.size;
381        });
382    }
383
384    gridElement.dispatchEvent(
385        new CustomEvent('closecolumnresize', { bubbles: true })
386    );
387    gridElement.focus();
388}
389
390export function resizeColumnDiscrete(gridElement, column, change) {
391    const isGrid = gridElement.classList.contains('grid');
392    const columns = [];
393    let headerBeingResized;
394
395    if (!column) {
396        const targetElement = document.activeElement.parentElement.parentElement.parentElement.parentElement;
397        if (!(targetElement.classList.contains("column-header") && targetElement.classList.contains("resizable"))) {
398            return;
399        }
400        headerBeingResized = targetElement;
401    }
402    else {
403        headerBeingResized = gridElement.querySelector('.column-header[col-index="' + column + '"]');
404    }
405
406
407    grids.find(({ id }) => id === gridElement.id).columns.forEach(column => {
408        if (column.header === headerBeingResized) {
409            const width = headerBeingResized.offsetWidth + change; //.getBoundingClientRect().width + change;
410
411            if (change < 0) {
412                column.size = Math.max(parseInt(column.header.style.minWidth), width) + 'px';
413            }
414            else {
415                column.size = width + 'px';
416            }
417            column.header.style.width = column.size;
418        }
419        if (isGrid) {
420            // for grid we need to recalculate all columns that are minmax
421            if (column.size.startsWith('minmax')) {
422                column.size = parseInt(column.header.clientWidth, 10) + 'px';
423            }
424            columns.push(column.size);
425        }
426    });
427
428    if (isGrid) {
429        gridElement.style.gridTemplateColumns = columns.join(' ');
430    }
431}
432
433export function resizeColumnExact(gridElement, column, width) {
434    const isGrid = gridElement.classList.contains('grid');
435    const columns = [];
436    let headerBeingResized = gridElement.querySelector('.column-header[col-index="' + column + '"]');
437
438    if (!headerBeingResized) {
439        return;
440    }
441
442    grids.find(({ id }) => id === gridElement.id).columns.forEach(column => {
443        if (column.header === headerBeingResized) {
444            column.size = Math.max(parseInt(column.header.style.minWidth), width) + 'px';
445            column.header.style.width = column.size;
446        }
447        if (isGrid) {
448            // for grid we need to recalculate all columns that are minmax
449            if (column.size.startsWith('minmax')) {
450                column.size = parseInt(column.header.clientWidth, 10) + 'px';
451            }
452            column.header.style.width = column.size;
453            columns.push(column.size);
454        }
455    });
456
457    if (isGrid) {
458        gridElement.style.gridTemplateColumns = columns.join(' ');
459    }
460
461    gridElement.dispatchEvent(new CustomEvent('closecolumnresize', { bubbles: true }));
462    gridElement.focus();
463}
464
465export function autoFitGridColumns(gridElement, columnCount) {
466    let gridTemplateColumns = '';
467
468    for (var i = 0; i < columnCount; i++) {
469        const columnWidths = Array
470            .from(gridElement.querySelectorAll(`[col-index="${i + 1}"]`))
471            .flatMap((x) => x.offsetWidth);
472
473        const maxColumnWidth = Math.max(...columnWidths);
474
475        gridTemplateColumns += ` ${maxColumnWidth}px`;
476    }
477
478    gridElement.style.gridTemplateColumns = gridTemplateColumns;
479    gridElement.classList.remove("auto-fit");
480
481    const grid = grids.find(grid => grid.id === gridElement.id);
482    if (grid) {
483        grid.initialWidths = gridTemplateColumns;
484    }
485}
486
487function calculateVisibleRows(gridElement, rowHeight) {
488    if (rowHeight <= 0) {
489        return 0;
490    }
491
492    const gridContainer = gridElement.parentElement;
493
494    if (!gridContainer) {
495        return 0;
496    }
497
498    const availableHeight = gridContainer?.clientHeight || window.visualViewport?.height || window.innerHeight;
499
500    const visibleRows = Math.max(Math.floor(availableHeight / rowHeight), 1);
501    return visibleRows;
502}
503
504export function dynamicItemsPerPage(gridElement, dotNetObject, rowSize) {
505    const observer = new ResizeObserver(() => {
506        const visibleRows = calculateVisibleRows(gridElement, rowSize)
507        dotNetObject.invokeMethodAsync('UpdateItemsPerPageAsync', visibleRows)
508            .catch(err => console.error("Error invoking Blazor method:", err));
509    });
510
511    const targetElement = gridElement.parentElement;
512    if (targetElement) {
513        observer.observe(targetElement);
514    }
515}

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.