UNPKG

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
/** * 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'); } } }