devexpress-reporting
Version:
DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.
164 lines (163 loc) • 7.15 kB
JavaScript
/**
* DevExpress HTML/JS Reporting (viewer\internal\_bindings.js)
* Version: 24.2.6
* Build date: Mar 18, 2025
* Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED
* License: https://www.devexpress.com/Support/EULAs/universal.xml
*/
import { ZoomAutoBy } from '../constants';
import { updatePreviewZoomWithAutoFit } from './_sizeUtils';
import { roundingXDecimals, $dx, guid } from '@devexpress/analytics-core/analytics-internal-native';
import { MultipageScrollingThrottle } from '../settings';
export function initializeToViewBinding(previewPage, options) {
const container = previewPage.closest('.dxrd-report-preview-holder'), dispose = options.setPageActiveChangedEvent((active) => {
if (active) {
const pageTop = previewPage.getBoundingClientRect().top;
const containerTop = container.getBoundingClientRect().top;
const pageHeight = previewPage.getBoundingClientRect().height;
const containerHeight = container.getBoundingClientRect().height;
if (pageTop < 0 && (pageTop + (pageHeight - containerTop) < 0) || pageTop >= containerHeight
|| (pageTop - (containerHeight + containerTop)) > 0) {
container.scrollTop = container.scrollTop + (pageTop - containerTop);
}
}
});
return dispose;
}
export function initializeLazyImagesBinding(element, options) {
let load = null;
const loadVisibleImages = (time = 300) => {
load && clearTimeout(load);
load = setTimeout(function () {
if (!options.getEnabled()) {
return;
}
const visibleArea = element.getBoundingClientRect().height + 100;
for (let i = 0; i < element.children.length; i++) {
const previewPage = element.children[i], rect = previewPage.getBoundingClientRect(), pageTop = rect.top;
if (visibleArea > pageTop && pageTop >= 0 || pageTop < 0 && pageTop + rect.height > -100) {
const previewPageModel = options.getPage(i);
if (previewPageModel?.isClientVisible === false) {
options.setPageVisibility(previewPageModel.getViewModel(), true);
}
}
}
}, time);
};
const dispose = options.setLoadVisibleImagesCallback(loadVisibleImages);
const scrollLoad = () => loadVisibleImages(MultipageScrollingThrottle());
element.addEventListener('scroll', scrollLoad);
loadVisibleImages(500);
return () => {
element.removeEventListener('scroll', scrollLoad);
dispose();
};
}
export function initializeTextCopierBinding(element, options) {
const keyDownHandler = function (e) {
const value = options.viewModel.getSelectedContent();
const target = e.target;
if (!value || !(e.ctrlKey || e.metaKey)
|| target.matches('textarea')
|| target.matches('input')
|| window.getSelection && window.getSelection() && window.getSelection().toString()
|| document['selection'] && document['selection'].createRange().text) {
return;
}
window.navigator.clipboard.writeText(value);
e.stopPropagation();
};
document.addEventListener('keydown', keyDownHandler);
return () => {
document.removeEventListener('keydown', keyDownHandler);
};
}
export function initializeAutoFitBinding(element, autoFitOptions) {
const updateZoom = () => {
const options = autoFitOptions.getPageSizeConfiguration();
const autoFitBy = options.autoFitBy;
if (autoFitBy != ZoomAutoBy.None) {
if (options.skipIfInvisible && !$dx(element).isVisible())
return;
const newZoom = roundingXDecimals(updatePreviewZoomWithAutoFit(options.width, options.height, element, autoFitBy), true);
Promise.resolve().then(() => autoFitOptions.setZoom(Math.max(newZoom, 0.1)));
}
};
updateZoom();
return autoFitOptions.setAutoFitChangedEvent(updateZoom);
}
export function initializeChildStyleBinding(element, values) {
$dx(element).find(values.selector).css(values.style);
}
export function initializeViewerExportBinding(element, exportHandlerViewModel) {
const exportHandler = exportHandlerViewModel.getModel();
let exportFrame = document.querySelector(`iframe[name="${exportHandler.exportingFrameName}"]`);
if (!exportFrame) {
exportFrame = document.createElement('iframe');
exportFrame.setAttribute('tabindex', '-1');
exportFrame.name = exportHandler.exportingFrameName;
exportFrame.setAttribute('role', 'none');
element.querySelector('.dxrd-visually-hidden').appendChild(exportFrame);
}
exportHandler.exportingFrame = exportFrame;
exportHandler.postingForm = element.querySelector('form');
}
function createSvgElement(imageData) {
const container = document.createElement('div');
container.innerHTML = imageData.svgMarkup;
const svg = container.querySelector('svg');
if (!svg)
return null;
const svgId = guid();
svg.id = svgId;
svg.querySelectorAll('clipPath').forEach(clip => {
clip.id += '_' + svgId;
});
svg.querySelectorAll('g').forEach(glyph => {
const clipPath = glyph.getAttribute('clip-path');
if (clipPath) {
const url = /#([^)]*)/.exec(clipPath)[1];
glyph.setAttribute('clip-path', `url(#${url}_${svgId})`);
}
});
return svg;
}
export function updatePreviewPageRendererBinding(element, imageData) {
const pointerEventsClass = 'dxrd-pointer-events-none';
const backupField = '__imageBackup';
const findImage = (imageType) => {
return Array.from(element.children).find(x => x.matches(imageType));
};
if (!imageData.svgMarkup || !imageData.useSvg) {
findImage('svg')?.remove();
let image = findImage('img');
if (!image) {
image = document.createElement('img');
image.style.setProperty('display', 'none');
image.setAttribute('aria-hidden', 'true');
element.prepend(image);
}
if (imageData.pageLoaded) {
image.style.removeProperty('display');
image.removeAttribute('aria-hidden');
}
image.setAttribute('src', imageData.displayImageSrc);
image.setAttribute('alt', imageData.currentPageAriaLabelImgAlt);
image.style.setProperty('background-color', imageData.color);
image.classList.add(pointerEventsClass, 'dxrd-width-100', 'dxrd-height-100');
}
else {
let svg = findImage('svg');
if (!svg || imageData.svgMarkup !== element[backupField]) {
svg?.remove();
svg = createSvgElement(imageData);
element[backupField] = imageData.svgMarkup;
}
if (svg) {
findImage('img')?.remove();
element.prepend(svg);
svg.setAttribute('width', imageData.width + 'px');
svg.setAttribute('height', imageData.height + 'px');
}
}
}