devexpress-reporting
Version:
DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.
75 lines (74 loc) • 3.3 kB
JavaScript
/**
* DevExpress HTML/JS Reporting (viewer\internal\_pageLoader.js)
* Version: 26.1.3
* Build date: Jun 16, 2026
* Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED
* License: https://www.devexpress.com/Support/EULAs/universal.xml
*/
import { delay } from '@devexpress/analytics-core/analytics-internal-native';
import { PreloadedPagesOffset } from '../settings';
export class PageLoadSession extends AbortController {
constructor() {
super(...arguments);
this._currentCycle = 0;
}
get aborted() {
return this.signal.aborted;
}
}
export class PagePrefetchService {
static _getNextStartIndex(reportPreview, currentIndex) {
return reportPreview.pages?.find?.(page => page?.pageIndex > currentIndex && !page.imageSrc)?.pageIndex;
}
static _getPagesToUpdate(previewPages, currentIndex, useOriginalResolution) {
const startIndex = useOriginalResolution ? Math.max(currentIndex - 2, 0) : currentIndex;
const endIndex = currentIndex + PreloadedPagesOffset();
const pages = previewPages.slice(startIndex, endIndex);
return useOriginalResolution ? pages : pages.filter(page => !page.imageSrc);
}
static _updatePages(reportPreview, pagesToUpdate, useOriginalResolution) {
const resolution = useOriginalResolution ? reportPreview.originalZoom : this._defaultResolution;
const forcePng = !useOriginalResolution;
pagesToUpdate.forEach(page => reportPreview.updatePage(page, resolution, forcePng));
}
static async _tryPerformPrefetch(pagesToUpdate, session) {
try {
await delay(PagePrefetchService._prefetchDelay, session.signal);
if (session.aborted)
return false;
const promises = pagesToUpdate.map(page => page.lastGetPageDeferred?.promise()).filter(x => !!x);
await Promise.all(promises);
return true;
}
catch (e) {
session.abort();
return false;
}
}
static async _prefetchPages(session, reportPreview, startIndex) {
let useOriginalResolution = true;
for (let i = 1; i <= this._requestCyclesLimit; i++) {
const pages = reportPreview.pages;
if (session.aborted || isNaN(startIndex) || startIndex >= pages.length || PreloadedPagesOffset() <= 0)
break;
session._currentCycle = i;
const pendingPages = this._getPagesToUpdate(pages, startIndex, useOriginalResolution);
this._updatePages(reportPreview, pendingPages, useOriginalResolution);
const success = await this._tryPerformPrefetch(pendingPages, session);
if (!success)
break;
startIndex = this._getNextStartIndex(reportPreview, startIndex);
useOriginalResolution = false;
}
session._currentCycle = null;
session.abort();
}
static prefetchPages(reportPreview, currentPageIndex) {
const controller = new PageLoadSession();
this._prefetchPages(controller, reportPreview, currentPageIndex);
return controller;
}
}
PagePrefetchService._defaultResolution = 0.25;
PagePrefetchService._requestCyclesLimit = 5;
PagePrefetchService._prefetchDelay = 700;