UNPKG

@syncfusion/ej2-pdfviewer

Version:
756 lines (755 loc) 31 kB
import { TextBox } from '@syncfusion/ej2-inputs'; import { Browser, createElement, isNullOrUndefined } from '@syncfusion/ej2-base'; import { Toolbar } from '@syncfusion/ej2-navigations'; import { CheckBox } from '@syncfusion/ej2-buttons'; import { selectTile, clearSelection } from './tile-interaction'; import { isOrganizeDialogRendered } from './organize-initialization'; import { enableDisableToolbarItems, enableToolbarItem, updateSelectAllCheckbox } from './organize-toolbar'; /** * @private * @returns { void } */ export function onToolbarExtractButtonClick() { // eslint-disable-next-line var proxy = this; // Allow extract only in client-side rendering mode if (!proxy.pdfViewerBase || !proxy.pdfViewerBase.clientSideRendering) { return; } var elementID = proxy.pdfViewer.element.id; var extractBtn = document.getElementById(elementID + '_extract_pages'); // Toggle secondary extract toolbar if (proxy.isExtractToolbarVisible) { destroySecondaryExtractToolbar.call(proxy); setOrganizeFooterForExtract.call(proxy, false); updateTileAreaHeightForSecondaryToolbar.call(proxy, false); proxy.isExtractToolbarVisible = false; if (extractBtn) { extractBtn.classList.remove('e-pv-select'); } } else { createSecondaryExtractToolbar.call(proxy); setOrganizeFooterForExtract.call(proxy, true); updateTileAreaHeightForSecondaryToolbar.call(proxy, true); proxy.isExtractToolbarVisible = true; if (extractBtn) { extractBtn.classList.add('e-pv-select'); } } } /** * @private * @returns { void } */ function createSecondaryExtractToolbar() { if (!this.pdfViewerBase || !this.pdfViewerBase.clientSideRendering) { return; } var elementID = this.pdfViewer.element.id; var toolbarHost = document.getElementById(elementID + '_toolbar_appearance'); // ensure button shows selected (bg) when opened var extractBtn = document.getElementById(elementID + '_extract_pages'); if (extractBtn) { extractBtn.classList.add('e-pv-select'); } if (!toolbarHost) { console.error('Toolbar host not found:', elementID + '_toolbar_appearance'); return; } // Create container for secondary toolbar var secondaryDiv = createElement('div', { id: elementID + "_extract_toolbar", className: 'e-pv-extract-toolbar' }); if (toolbarHost.parentElement) { // If nextSibling is null, insertBefore behaves like appendChild toolbarHost.parentElement.insertBefore(secondaryDiv, toolbarHost.nextSibling); } else { toolbarHost.appendChild(secondaryDiv); } function pageInputTemplate() { var inputElement = createElement('input', { id: elementID + "_page_input", attrs: { type: 'text' } }); return inputElement.outerHTML; } function deleteCheckTemplate() { var checkboxElement = createElement('input', { id: elementID + "_extract_delete", attrs: { type: 'checkbox' } }); return checkboxElement.outerHTML; } function separateCheckTemplate() { var checkboxElement = createElement('input', { id: elementID + "_extract_separate", attrs: { type: 'checkbox' } }); return checkboxElement.outerHTML; } // Toolbar items var items = [ { id: elementID + "_extract_pages_input_item", type: 'Input', template: pageInputTemplate(), align: 'Center' }, { type: 'Separator', align: 'Center' }, { id: elementID + "_extract_delete_cb_item", template: deleteCheckTemplate(), align: 'Center' }, { id: elementID + "_extract_separate_cb_item", template: separateCheckTemplate(), align: 'Center' } ]; var secondaryToolbar = new Toolbar({ items: items, overflowMode: 'Scrollable' }); secondaryToolbar.appendTo(secondaryDiv); // Ensure overflow calculations are correct at first paint (prevents item overlap) if (secondaryToolbar.refreshOverflow) { try { secondaryToolbar.refreshOverflow(); } catch (e) { /* no-op */ } } // Also keep it responsive on window resize function resizeHandler() { if (secondaryToolbar.refreshOverflow) { try { secondaryToolbar.refreshOverflow(); } catch (e) { /* no-op */ } } } window.addEventListener('resize', resizeHandler); this.extractToolbarResizeHandler = resizeHandler; // Force proper centering of the middle group items var centerGroup = secondaryDiv.querySelector('.e-toolbar-center'); var centerItems = secondaryDiv.querySelector('.e-toolbar-center .e-toolbar-items'); if (centerGroup) { centerGroup.classList.add('e-pv-center-group-style'); } if (centerItems) { centerItems.classList.add('e-pv-center-items-style'); } var leftGroup = secondaryDiv.querySelector('.e-toolbar-left'); var rightGroup = secondaryDiv.querySelector('.e-toolbar-right'); // Ensure side groups don't reserve unexpected space if (leftGroup) { leftGroup.style.flex = '0 0 auto'; } if (rightGroup) { rightGroup.style.flex = '0 0 auto'; } // Provide comfortable spacing and left alignment within center group var centerToolbarItems = secondaryDiv.querySelectorAll('.e-toolbar-center .e-toolbar-item'); centerToolbarItems.forEach(function (el) { // Skip separators for spacing if (!el.classList.contains('e-separator')) { el.style.marginRight = '12px'; } }); var inputHost = document.getElementById(elementID + '_page_input'); if (inputHost) { var textBox = new TextBox({ placeholder: this.pdfViewer.localeObj.getConstant('Example: 1,3,5-12'), floatLabelType: 'Never', width: Browser.isDevice ? '140px' : '220px' }); textBox.appendTo(inputHost); this.extractPagesInput = textBox; if (secondaryToolbar.refreshOverflow) { try { secondaryToolbar.refreshOverflow(); } catch (e) { /* no-op */ } } } var separateHost = document.getElementById(elementID + '_extract_separate'); if (separateHost) { var seperateCheckboxLabel = (this.pdfViewer.localeObj && this.pdfViewer.localeObj.getConstant('Extract Pages As Separate Files')); var separateCheckbox = new CheckBox({ label: seperateCheckboxLabel, checked: false }); separateCheckbox.appendTo(separateHost); var wrap = separateHost.closest('.e-toolbar-item'); if (wrap) { wrap.style.overflow = 'visible'; } if (secondaryToolbar.refreshOverflow) { try { secondaryToolbar.refreshOverflow(); } catch (e) { /* no-op */ } } } var deleteHost = document.getElementById(elementID + '_extract_delete'); if (deleteHost) { var deleteCheckboxLabel = (this.pdfViewer.localeObj && this.pdfViewer.localeObj.getConstant('Delete Pages After Extracting')); var deleteCheckbox = new CheckBox({ label: deleteCheckboxLabel, checked: false }); deleteCheckbox.appendTo(deleteHost); var wrap = deleteHost.closest('.e-toolbar-item'); if (wrap) { wrap.classList.add('extract_delete_center_div'); wrap.style.overflow = 'visible'; } if (secondaryToolbar.refreshOverflow) { try { secondaryToolbar.refreshOverflow(); } catch (e) { /* no-op */ } } } if (!isNullOrUndefined(this.extractPagesInput)) { inputTextboxUpdate.call(this); updateExtractOkButtonState.call(this); initExtractEventListeners.call(this); } var seperateElementss = secondaryDiv.getElementsByClassName('e-separator'); for (var i = 0; i < seperateElementss.length; i++) { var element = seperateElementss[parseInt(i.toString(), 10)]; if (element) { element.setAttribute('tabindex', '0'); element.setAttribute('data-tabindex', '0'); } } this.extractSecondaryToolbar = secondaryToolbar; } /** * @private * @returns {number[]} - selected tile nodes in organize window. */ export function selectedNodesInOrganizeWindow() { var selectedNodes = this.tileAreaDiv.querySelectorAll('.e-pv-organize-node-selection-ring'); var selectedPages = []; selectedNodes.forEach(function (selectedElement) { var mainTileElement = selectedElement.closest('.e-pv-organize-anchor-node'); if (mainTileElement) { var pageOrderAttr = mainTileElement.getAttribute('data-page-order'); if (pageOrderAttr !== null) { selectedPages.push(parseInt(pageOrderAttr, 10) + 1); } } }); return selectedPages; } /** * @private * @returns { void } */ function destroySecondaryExtractToolbar() { // Unwire extract-specific listeners first try { removeExtractEventListeners.call(this); } catch (e) { /* no-op */ } var elementID = this.pdfViewer.element.id; var secondaryDiv = document.getElementById(elementID + "_extract_toolbar"); var toolbar = this.extractSecondaryToolbar; var extractBtn = document.getElementById(elementID + '_extract_pages'); if (extractBtn) { extractBtn.classList.remove('e-pv-select'); } // Remove resize listener if attached var resizeHandler = this.extractToolbarResizeHandler; if (resizeHandler) { window.removeEventListener('resize', resizeHandler); this.extractToolbarResizeHandler = null; } if (toolbar) { toolbar.destroy(); this.extractSecondaryToolbar = null; } if (secondaryDiv && secondaryDiv.parentElement) { secondaryDiv.parentElement.removeChild(secondaryDiv); } this.extractPagesInput = null; } /** * @private * @param {boolean} showExtract - Whether to show extract footer buttons. * @returns { void } */ function setOrganizeFooterForExtract(showExtract) { var _this = this; if (!this.organizeDialog) { return; } var dlgEle = this.organizeDialog.element; var isMobileUI = Browser.isDevice; if (showExtract) { // When extract toolbar is visible, always show Cancel/Extract this.organizeDialog.buttons = [ { buttonModel: { content: this.pdfViewer.localeObj.getConstant('Cancel') }, click: function () { destroySecondaryExtractToolbar.call(_this); setOrganizeFooterForExtract.call(_this, false); updateTileAreaHeightForSecondaryToolbar.call(_this, false); _this.isExtractToolbarVisible = false; } }, { buttonModel: { content: this.pdfViewer.localeObj.getConstant('Extract'), isPrimary: true, cssClass: 'e-pv-extractbtn', disabled: !(this.extractPagesInput && this.extractPagesInput.value && this.extractPagesInput.value.trim() !== '') }, click: onExtractConfirmClick.bind(this) } ]; } else { if (isMobileUI) { // No footer on mobile when extract toolbar is hidden this.organizeDialog.buttons = []; } else { var pagecount = this.pdfViewerBase.pageCount; this.organizeDialog.buttons = [ { buttonModel: { content: this.pdfViewer.localeObj.getConstant('Save As'), isPrimary: true }, click: this.onSaveasClicked.bind(this) }, { buttonModel: { content: this.pdfViewer.localeObj.getConstant('Save'), isPrimary: true }, click: this.onSaveClicked.bind(this) }, { buttonModel: { content: this.pdfViewer.localeObj.getConstant('Total') + ' ' + pagecount.toString() + ' ' + this.pdfViewer.localeObj.getConstant('Pages'), cssClass: 'e-pv-organize-total-page-button', disabled: true } } ]; } } this.organizeDialog.dataBind(); // Ensure the footer DOM is actually hidden/shown as required var footerContent = dlgEle.querySelector('.e-footer-content'); var footerBar = dlgEle.querySelector('.e-dlg-footer'); // Add a strong CSS rule once to reliably hide footer on mobile when needed var HIDE_CLASS = 'e-pv-hide-footer'; var STYLE_ID = 'e-pv-hide-footer-style'; if (!document.getElementById(STYLE_ID)) { var styleEl = document.createElement('style'); styleEl.id = STYLE_ID; styleEl.textContent = "\n .e-dialog." + HIDE_CLASS + " .e-footer-content,\n .e-dialog." + HIDE_CLASS + " .e-dlg-footer { display: none !important; }\n "; document.head.appendChild(styleEl); } if (showExtract) { // Ensure footer exists and is visible for Cancel/Extract if (footerBar) { footerBar.style.display = ''; } if (footerContent) { footerContent.style.display = ''; } dlgEle.classList.remove(HIDE_CLASS); dlgEle.removeAttribute('data-hide-footer'); } else if (isMobileUI) { // Hide and remove footer entirely on mobile when extract toolbar is hidden if (footerContent && footerContent.parentElement) { footerContent.parentElement.removeChild(footerContent); } if (footerBar && footerBar.parentElement) { footerBar.parentElement.removeChild(footerBar); } dlgEle.classList.add(HIDE_CLASS); dlgEle.setAttribute('data-hide-footer', 'true'); } else { // Desktop: keep footer visible if (footerBar) { footerBar.style.display = ''; } if (footerContent) { footerContent.style.display = ''; } dlgEle.classList.remove(HIDE_CLASS); dlgEle.removeAttribute('data-hide-footer'); } } /** * @private * @param {boolean} show - Whether to adjust tile area height for secondary toolbar. * @returns { void } */ function updateTileAreaHeightForSecondaryToolbar(show) { if (this.tileAreaWrapper) { this.tileAreaWrapper.style.height = show ? 'calc(100% - 96px)' : 'calc(100% - 48px)'; } } /** * @private * @returns { void } */ function updateExtractOkButtonState() { var inputValue = this.extractPagesInput ? this.extractPagesInput.value.trim() : ''; var createBtn = document.getElementsByClassName('e-pv-extractbtn')[0]; if (createBtn) { createBtn.disabled = inputValue === ''; } } /** * @private * @param {string} input - extract pages input string. * @param {number} pageCount - total number of tiles in the organize window. * @returns { string } - Formatted page ranges. */ export function formatPageRanges(input, pageCount) { var validPages = []; if (input) { var parts = input.split(','); for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { var part = parts_1[_i]; part = part.trim(); if (/^\d+$/.test(part)) { var value = parseInt(part, 10); if (value >= 1 && value <= pageCount) { validPages.push(value); } } else if (/^\d+-\d+$/.test(part)) { var _a = part.split('-').map(function (n) { return parseInt(n, 10); }), start_1 = _a[0], end_1 = _a[1]; if (start_1 >= 1 && end_1 <= pageCount && start_1 <= end_1) { for (var i = start_1; i <= end_1; i++) { validPages.push(i); } } } } validPages.sort(function (a, b) { return a - b; }); var uniquePages = Array.from(new Set(validPages)); var ranges = []; var start = uniquePages[0]; var end = start; for (var i = 1; i < uniquePages.length; i++) { if (uniquePages[parseInt(i.toString(), 10)] === end + 1) { end = uniquePages[parseInt(i.toString(), 10)]; } else { ranges.push(start === end ? "" + start : start + "-" + end); start = uniquePages[parseInt(i.toString(), 10)]; end = start; } } if (start !== undefined) { ranges.push(start === end ? "" + start : start + "-" + end); } var output = ''; if (ranges.length > 0) { output = ranges[0]; for (var i = 1; i < ranges.length; i++) { var prevIsRange = ranges[parseInt(i.toString(), 10) - 1].indexOf('-') !== -1; var currIsRange = ranges[parseInt(i.toString(), 10)].indexOf('-') !== -1; var sep = (prevIsRange && currIsRange) ? ',' : ', '; output += sep + ranges[parseInt(i.toString(), 10)]; } } return output; } return ''; } /** * @private * @returns { void } */ export function onExtractConfirmClick() { var _this = this; if (!this.pdfViewerBase || !this.pdfViewerBase.clientSideRendering) { return; } var value = this.extractPagesInput ? this.extractPagesInput.value.trim() : ''; var fileName = this.pdfViewer.fileName; var downloadFileName = this.pdfViewer.downloadFileName; var elementID = this.pdfViewer.element.id; var isSeparateChecked = document.getElementById(elementID + '_extract_separate') ? document.getElementById(elementID + '_extract_separate').checked : false; var isDeleteChecked = document.getElementById(elementID + '_extract_delete') ? document.getElementById(elementID + '_extract_delete').checked : false; if (!value) { return; } var pageList = parsePageList.call(this, value); this.pdfViewerBase.extractAction = true; var selectedPages = selectedNodesInOrganizeWindow.call(this); // Case 1: Combined PDF download if (!isSeparateChecked && !isDeleteChecked) { var byteArray = this.pdfViewer.extractPages(value); if (byteArray) { this.pdfViewerBase.fileDownload(byteArray, this.pdfViewerBase, false, true); } } // Case 2: Delete pages after extracting (combined PDF) else if (isDeleteChecked && !isSeparateChecked) { var byteArray = this.pdfViewer.extractPages(value); if (byteArray && byteArray.length > 0) { this.pdfViewerBase.fileDownload(byteArray, this.pdfViewerBase, false, true); if (selectedPages.length === this.tileAreaDiv.childElementCount) { this.pdfViewer.loadDocInternally(this.pdfViewerBase.currentDocumentByteArray, this.pdfViewer.pdfRendererModule.password, false); } else { var remainingPages = this.pdfViewer.importPagesFromRange(!isNullOrUndefined(this.deleteExtractValue) && this.deleteExtractValue !== '' ? this.deleteExtractValue : value, this.pdfViewerBase.currentDocumentByteArray, true); this.pdfViewer.loadDocInternally(remainingPages, this.pdfViewer.pdfRendererModule.password, false); } } this.isOrganizeWindowOpen = false; this.pdfViewer.isPageOrganizerOpen = false; this.deleteExtractValue = ''; } // Case 3: Separate PDFs else if (isSeparateChecked && !isDeleteChecked) { pageList.forEach(function (pageNum) { var singlePageByteArray = _this.pdfViewer.extractPages(pageNum.toString()); if (singlePageByteArray) { _this.pdfViewerBase.fileDownload(singlePageByteArray, _this.pdfViewerBase, false, true); } }); } // Case 4: Separate PDFs + delete pages else if (isSeparateChecked && isDeleteChecked) { pageList.forEach(function (pageNum) { var singlePageByteArray = _this.pdfViewer.extractPages(pageNum.toString()); if (singlePageByteArray) { _this.pdfViewerBase.fileDownload(singlePageByteArray, _this.pdfViewerBase, false, true); } }); if (selectedPages.length === this.tileAreaDiv.childElementCount) { this.pdfViewer.loadDocInternally(this.pdfViewerBase.currentDocumentByteArray, this.pdfViewer.pdfRendererModule.password, false); } else { var remainingPages = this.pdfViewer.importPagesFromRange(!isNullOrUndefined(this.deleteExtractValue) && this.deleteExtractValue !== '' ? this.deleteExtractValue : value, this.pdfViewerBase.currentDocumentByteArray, true); this.pdfViewer.loadDocInternally(remainingPages, this.pdfViewer.pdfRendererModule.password, false); } this.isOrganizeWindowOpen = false; this.pdfViewer.isPageOrganizerOpen = false; this.deleteExtractValue = ''; } this.pdfViewer.fileName = fileName; this.pdfViewer.downloadFileName = downloadFileName || fileName; this.pdfViewerBase.currentDocumentByteArray = new Uint8Array(0); if (this.extractDialog) { this.extractDialog.hide(); } // If secondary toolbar mode is active, close it and restore footer/buttons if (this.isExtractToolbarVisible) { destroySecondaryExtractToolbar.call(this); setOrganizeFooterForExtract.call(this, false); updateTileAreaHeightForSecondaryToolbar.call(this, false); this.isExtractToolbarVisible = false; } } /** * @private * @param {string} value - extract pages input string. * @returns { number[] } - parsed page list. */ function parsePageList(value) { var parts = value.split(','); var pageList = []; for (var _i = 0, parts_2 = parts; _i < parts_2.length; _i++) { var part = parts_2[_i]; var trimmed = part.trim(); if (trimmed.includes('-')) { var _a = trimmed.split('-'), startStr = _a[0], endStr = _a[1]; var start = parseInt(startStr, 10); var end = parseInt(endStr, 10); if (!isNaN(start) && !isNaN(end) && start <= end) { for (var i = start; i <= end; i++) { pageList.push(i); } } } else { var num = parseInt(trimmed, 10); if (!isNaN(num)) { pageList.push(num); } } } return pageList; } /** * @private * @param {boolean} isInitialState - Whether it's the initial toolbar state. * @param {ItemModel[]} toolbarItems - Toolbar items array. * @returns { void } */ export function addExtractionIcon(isInitialState, toolbarItems) { var _this = this; if (isInitialState) { // Remove extract icon if setting is disabled or not client-side rendering if (!this.pdfViewer.pageOrganizerSettings.showExtractPagesOption || !this.pdfViewerBase.clientSideRendering) { var extractIndex = toolbarItems.findIndex(function (item) { return item.id === _this.pdfViewer.element.id + '_extract_pages'; }); if (extractIndex !== -1) { toolbarItems.splice(extractIndex, 1); } } } } /** * @private * @param {boolean} showExtractPagesOption - Whether to show or remove extract icon. * @returns { void } */ export function showRemoveExtractIcon(showExtractPagesOption) { var elementID = this.pdfViewer.element.id; var extractIconId = elementID + '_extract_pages'; if (!isOrganizeDialogRendered.call(this)) { return; } // If not client-side rendering, treat as not visible if (!showExtractPagesOption || !this.pdfViewerBase.clientSideRendering) { var extractIndex = this.toolbar.items.findIndex(function (item) { return item.id === extractIconId; }); if (extractIndex !== -1) { var iconElement = this.pdfViewerBase.getElement('_extract_pages'); if (iconElement && iconElement.parentElement) { if (Browser.isDevice && !this.pdfViewer.enableDesktopMode) { this.toolbar.hideItem(iconElement.parentElement, true); } else { this.toolbar.removeItems(iconElement.parentElement); } } } // If extract toolbar is open, close it and restore default footer/layout if (this.isExtractToolbarVisible) { destroySecondaryExtractToolbar.call(this); setOrganizeFooterForExtract.call(this, false); updateTileAreaHeightForSecondaryToolbar.call(this, false); this.isExtractToolbarVisible = false; } // Clean up any previously attached desktop click handler reference to avoid duplicates detachExtractButtonHandler.call(this); } else { if (Browser.isDevice && !this.pdfViewer.enableDesktopMode) { var extractIndex = this.toolbar.items.findIndex(function (item) { return item.id === extractIconId; }); if (extractIndex !== -1) { this.toolbar.hideItem(this.pdfViewerBase.getElement('_extract_pages').parentElement, false); } else { var moreIndex = this.toolbar.items.findIndex(function (item) { return item.id === (elementID + '_organize_more_button'); }); var insertIndex = moreIndex > -1 ? moreIndex : this.toolbar.items.length; var itemsToAdd = []; itemsToAdd.push({ visible: true, cssClass: 'e-pv-extract-pages', prefixIcon: 'e-pv-extract-page-icon e-pv-icon', id: extractIconId, align: 'Right' }); this.toolbar.addItems(itemsToAdd, insertIndex); } } else { var insertIndex = this.toolbar.items.findIndex(function (item) { return item.cssClass === 'e-pv-import-pages'; }); var itemsToAdd = []; if (insertIndex > 0 && this.toolbar.items[insertIndex - 1].type !== 'Separator') { itemsToAdd.push({ type: 'Separator', align: 'Center' }); } itemsToAdd.push({ visible: true, cssClass: 'e-pv-extract-pages', prefixIcon: 'e-pv-extract-page-icon e-pv-icon', id: extractIconId, align: 'Center' }); this.toolbar.addItems(itemsToAdd, insertIndex); } var extractButton = document.getElementById(extractIconId); if (extractButton && !Browser.isDevice) { attachExtractButtonHandler.call(this, extractButton); } if (!this.pdfViewer.pageOrganizerSettings.canExtractPages || !this.pdfViewerBase.clientSideRendering) { enableToolbarItem.call(this, this.pdfViewer.element.id + '_extract_pages', false); } } } /** * @private * @param {boolean} canExtractPages - Whether to enable or disable extract icon. * @returns { void } */ export function showHideExtractIcon(canExtractPages) { if (!isOrganizeDialogRendered.call(this)) { return; } var enable = canExtractPages && this.pdfViewerBase.clientSideRendering; enableToolbarItem.call(this, this.pdfViewer.element.id + '_extract_pages', enable); // If disabling while the extract toolbar is open, close and restore footer/layout if (!enable && this.isExtractToolbarVisible) { destroySecondaryExtractToolbar.call(this); setOrganizeFooterForExtract.call(this, false); updateTileAreaHeightForSecondaryToolbar.call(this, false); this.isExtractToolbarVisible = false; } } /** * @private * @returns { void } */ export function inputTextboxUpdate() { var selectedPages = selectedNodesInOrganizeWindow.call(this); if (!isNullOrUndefined(this.extractPagesInput)) { var formatted = formatPageRanges(selectedPages.join(','), this.tileAreaDiv.childElementCount); // Update component value this.extractPagesInput.value = formatted; this.extractPagesInput.dataBind(); // Also ensure the native input reflects the latest value if (this.extractPagesInput.element) { this.extractPagesInput.element.value = formatted; } // Update Extract button enable state try { updateExtractOkButtonState.call(this); } catch (_) { /* no-op */ } } } /** * @private * @returns { void } */ function initExtractEventListeners() { var _this = this; if (this.boundExtractInputChange) { return; } if (!this.extractPagesInput || !this.extractPagesInput.element) { return; } // Capture PageOrganizer context using an arrow function and add explicit typedef for lint compliance var changeHandler = function () { // Normalize user input to valid formatted ranges _this.extractPagesInput.value = formatPageRanges.call(_this, _this.extractPagesInput.value, _this.tileAreaDiv.childElementCount); var pagesToSelect = parsePageList.call(_this, _this.extractPagesInput.value); clearSelection.call(_this); pagesToSelect.forEach(function (pageNum) { var index = pageNum - 1; // data-page-order is zero-based var tile = _this.tileAreaDiv.querySelector("[data-page-order=\"" + index + "\"]"); if (tile) { selectTile.call(_this, tile); } }); updateExtractOkButtonState.call(_this); try { updateSelectAllCheckbox.call(_this); } catch (_) { /* no-op */ } try { enableDisableToolbarItems.call(_this); } catch (_) { /* no-op */ } }; this.boundExtractInputChange = changeHandler; this.extractPagesInput.element.addEventListener('change', changeHandler); } /** * @private * @returns { void } */ function removeExtractEventListeners() { var bound = this.boundExtractInputChange; if (this.extractPagesInput && this.extractPagesInput.element && bound) { this.extractPagesInput.element.removeEventListener('change', bound); } this.boundExtractInputChange = null; } /** * @private * @param {HTMLElement} button - Extract toolbar button element. * @returns { void } */ function attachExtractButtonHandler(button) { // Unbind any existing first to avoid duplicates detachExtractButtonHandler.call(this); var handler = onToolbarExtractButtonClick.bind(this); this.extractButtonClickHandler = handler; this.extractButtonElement = button; button.addEventListener('click', handler); } /** * @private * @returns { void } */ function detachExtractButtonHandler() { if (this.extractButtonClickHandler && this.extractButtonElement) { this.extractButtonElement.removeEventListener('click', this.extractButtonClickHandler); } this.extractButtonClickHandler = null; this.extractButtonElement = null; }