jQuery( function( $ ) { $( '.wcpdf-extensions .more' ).hide(); $( '.wcpdf-extensions > li' ).on( 'click', function( event ) { $( this ).toggleClass( 'expanded' ); $( this ).find( '.more' ).slideToggle(); } ); $( '.edit-next-number' ).on( 'click', function( event ) { // enable input & show save button $( this ).hide(); $( this ).siblings( 'input' ).prop( 'disabled', false ); $( this ).siblings( '.save-next-number.button' ).show(); } ); $( '.save-next-number' ).on( 'click', function( event ) { $input = $( this ).siblings( 'input' ); $input.addClass( 'ajax-waiting' ); let number = $input.val(); if ( number.length > 0 && number > 2147483647 ) { alert( wpo_wcpdf_admin.mysql_int_size_limit ); $input.removeClass( 'ajax-waiting' ); return; } let data = { security: $input.data( 'nonce' ), action: 'wpo_wcpdf_set_next_number', store: $input.data( 'store' ), number: number, }; xhr = $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, success: function( response ) { $input.removeClass( 'ajax-waiting' ); $input.siblings( '.edit-next-number' ).show(); $input.prop( 'disabled', 'disabled' ); $input.siblings( '.save-next-number.button' ).hide(); } } ); } ); $( "[name='wpo_wcpdf_documents_settings_invoice[display_number]']" ).on( 'change', function( event ) { if ( $( this ).val() == 'order_number' ) { $( this ).closest( 'td' ).find( '.description' ).slideDown(); $( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().hide(); } else { $( this ).closest( 'td' ).find( '.description' ).hide(); $( this ).closest( 'tr' ).nextAll( 'tr' ).has( 'input#next_invoice_number' ).first().show(); } } ).trigger( 'change' ); // enable settings document switch $( '.wcpdf_document_settings_sections > h2' ).on( 'click', function() { $( this ).parent().find( 'ul' ).toggleClass( 'active' ); } ); // Add admin pointers $.each( wpo_wcpdf_admin.pointers, function( key, pointer ) { $( pointer.target ).pointer( { content: pointer.content, position: { edge: pointer.position.edge, align: pointer.position.align }, pointerClass: pointer.pointer_class, pointerWidth: pointer.pointer_width, close: function() { jQuery.post( wpo_wcpdf_admin.ajaxurl, { pointer: key, action: 'dismiss-wp-pointer', } ); }, } ); // Check if pointer was dismissed if ( $.inArray( key, wpo_wcpdf_admin.dismissed_pointers.split(',') ) === -1 ) { $( pointer.target ).pointer('open'); } }); // enable WooCommerce help tips $( '.woocommerce-help-tip' ).tipTip( { 'attribute': 'data-tip', 'fadeIn': 50, 'fadeOut': 50, 'delay': 200 } ); $( '#wpo-wcpdf-preview-wrapper #due_date' ).on( 'change', function() { const $due_date_checkbox = $( '#wpo-wcpdf-preview-wrapper #due_date' ); const $due_date_days_input = $( '#wpo-wcpdf-preview-wrapper #due_date_days' ); if ( $due_date_checkbox.is( ':checked' ) ) { $due_date_days_input.prop( 'disabled', false ); } else { $due_date_days_input.prop( 'disabled', true ); } } ).trigger( 'change' ); //----------> Preview <----------// // objects let $previewWrapper = $( '#wpo-wcpdf-preview-wrapper' ); let $preview = $( '#wpo-wcpdf-preview-wrapper .preview' ); let $previewOrderIdInput = $( '#wpo-wcpdf-preview-wrapper input[name="order_id"]' ); let $previewDocumentTypeInput = $( '#wpo-wcpdf-preview-wrapper input[name="document_type"]' ); let $previewOutputFormatInput = $( '#wpo-wcpdf-preview-wrapper input[name="output_format"]' ); let $previewNonceInput = $( '#wpo-wcpdf-preview-wrapper input[name="nonce"]' ); let $previewSettingsForm = $( '#wpo-wcpdf-settings' ); let previewXhr = null; // variables let previewOrderId, previewDocumentType, previewOutputFormat, previewNonce, previewSettingsFormData, previewTimeout, previewSearchTimeout, previousWindowWidth; function loadPreviewData() { previewOrderId = $previewOrderIdInput.val(); previewDocumentType = $previewDocumentTypeInput.val(); previewOutputFormat = $previewOutputFormatInput.val(); previewNonce = $previewNonceInput.val(); previewSettingsFormData = $previewSettingsForm.serialize(); } function resetDocumentType() { $previewDocumentTypeInput.val( $previewDocumentTypeInput.data( 'default' ) ).trigger( 'change' ); } function resetOrderId() { $previewOrderIdInput.val( '' ).trigger( 'change' ); } resetDocumentType(); // force document type reset resetOrderId(); // force order ID reset loadPreviewData(); // load preview data previousWindowWidth = $( window ).width(); determinePreviewStates(); // determine preview states based on screen size $( window ).on( 'resize', determinePreviewStates ); function determinePreviewStates() { // Check if preview states are allowed to change based on screen size if ( $previewWrapper.attr( 'data-preview-states-lock') == false ) { // On small screens: 2 preview states and close preview if ( $(this).width() <= 1200 && ( previousWindowWidth > 1200 || $(this).width() == previousWindowWidth ) ) { if ( $previewWrapper.attr( 'data-preview-state') == 'full' ) { $previewWrapper.find( '.preview-document' ).show(); $previewWrapper.find( '.sidebar' ).hide(); $previewWrapper.find( '.slide-left' ).hide(); $previewWrapper.find( '.slide-right' ).show(); $previewWrapper.attr( 'data-preview-states', 2 ); $previewWrapper.attr( 'data-preview-state', 'full' ); $previewWrapper.attr( 'data-from-preview-state', '' ); } else { $previewWrapper.find( '.preview-document' ).hide(); $previewWrapper.find( '.sidebar' ).show(); $previewWrapper.find( '.slide-left' ).show(); $previewWrapper.find( '.slide-right' ).hide(); $previewWrapper.attr( 'data-preview-states', 2 ); $previewWrapper.attr( 'data-preview-state', 'closed' ); $previewWrapper.attr( 'data-from-preview-state', '' ); } // On larger screens: 3 preview states and show settings as sidebar } else if ( $(this).width() > 1200 && ( previousWindowWidth <= 1200 || $(this).width() == previousWindowWidth ) ) { if ( $previewWrapper.attr( 'data-preview-state') == 'full' ) { $previewWrapper.find( '.preview-document' ).show(); $previewWrapper.find( '.sidebar' ).hide(); $previewWrapper.find( '.slide-left' ).hide(); $previewWrapper.find( '.slide-right' ).show(); $previewWrapper.attr( 'data-preview-states', 3 ); $previewWrapper.attr( 'data-preview-state', 'full' ); $previewWrapper.attr( 'data-from-preview-state', 'sidebar' ); $previewWrapper.addClass( 'static' ); } else if ( $previewWrapper.attr( 'data-preview-state') == 'closed' && $(this).width() !== previousWindowWidth ) { $previewWrapper.find( '.preview-document' ).hide(); $previewWrapper.find( '.sidebar' ).show(); $previewWrapper.find( '.slide-left' ).show(); $previewWrapper.find( '.slide-right' ).hide(); $previewWrapper.attr( 'data-preview-states', 3 ); $previewWrapper.attr( 'data-preview-state', 'closed' ); $previewWrapper.attr( 'data-from-preview-state', '' ); $previewWrapper.removeClass( 'static' ); } else { $previewWrapper.find( '.preview-document, .sidebar' ).show(); $previewWrapper.find( '.slide-left, .slide-right' ).show(); $previewWrapper.attr( 'data-preview-states', 3 ); $previewWrapper.attr( 'data-preview-state', 'sidebar' ); $previewWrapper.attr( 'data-from-preview-state', '' ); $previewWrapper.removeClass( 'static' ); } } } previousWindowWidth = $(this).width(); } $( '.slide-left' ).on( 'click', function() { let previewStates = $previewWrapper.attr( 'data-preview-states' ); let previewState = $previewWrapper.attr( 'data-preview-state' ); $previewWrapper.find( '.preview-data-wrapper ul' ).removeClass( 'active' ); if ( previewStates == 3 ) { if ( previewState == 'closed' ) { $previewWrapper.find( '.preview-document' ).show(); $previewWrapper.find( '.slide-right' ).show(); $previewWrapper.attr( 'data-preview-state', 'sidebar' ); $previewWrapper.attr( 'data-from-preview-state', 'closed' ); } else { $previewWrapper.find( '.slide-left' ).hide(); $previewWrapper.find( '.sidebar' ).delay(300).hide(0); $previewWrapper.attr( 'data-preview-state', 'full' ); $previewWrapper.attr( 'data-from-preview-state', 'sidebar' ); makePreviewScrollable( $previewWrapper ); } } else { $previewWrapper.find( '.preview-document' ).show(); $previewWrapper.find( '.slide-left' ).hide(); $previewWrapper.find( '.slide-right' ).show(); $previewWrapper.attr( 'data-preview-state', 'full' ); $previewWrapper.attr( 'data-from-preview-state', 'closed' ); makePreviewScrollable( $previewWrapper ); } } ); $( '.slide-right' ).on( 'click', function() { let previewStates = $previewWrapper.attr( 'data-preview-states' ); let previewState = $previewWrapper.attr( 'data-preview-state' ); $previewWrapper.find( '.preview-data-wrapper ul' ).removeClass( 'active' ); if ( previewStates == 3 ) { if ( previewState == 'full' ) { $previewWrapper.find( '.slide-left' ).delay(400).show(0); $previewWrapper.find( '.sidebar' ).show(); $previewWrapper.attr( 'data-preview-state', 'sidebar' ); $previewWrapper.attr( 'data-from-preview-state', 'full' ); } else { $previewWrapper.find( '.preview-document' ).hide(300); $previewWrapper.find( '.slide-right' ).hide(); $previewWrapper.attr( 'data-preview-state', 'closed' ); $previewWrapper.attr( 'data-from-preview-state', 'sidebar' ); } } else { $previewWrapper.find( '.preview-document' ).hide(300); $previewWrapper.find( '.slide-left' ).show(); $previewWrapper.find( '.slide-right' ).hide(); $previewWrapper.attr( 'data-preview-state', 'closed' ); $previewWrapper.attr( 'data-from-preview-state', 'full' ); } $previewWrapper.removeClass( 'static' ); } ); function makePreviewScrollable( wrapper ) { window.scrollTo( 0, 0 ); let $wrapper = wrapper; // Make preview scrollable after panel animation is complete setTimeout( function() { $wrapper.addClass( 'static' ); }, 300 ); } $( '.preview-document .preview-data p' ).on( 'click', function() { let $previewData = $( this ).closest( '.preview-data' ); $previewData.siblings( '.preview-data' ).find( 'ul' ).removeClass( 'active' ); $previewData.find( 'ul' ).toggleClass( 'active' ); } ); $( '.preview-document .preview-data ul > li' ).on( 'click', function() { let $previewData = $( this ).closest( '.preview-data' ); $previewData.find( 'ul' ).toggleClass( 'active' ); if ( $( this ).hasClass( 'order-search' ) ) { $previewData.find( 'p.last-order' ).hide(); $previewData.find( 'input[name="preview-order-search"]' ).addClass( 'active' ); $previewData.find( 'p.order-search' ).show().find( '.order-search-label' ).text( $( this ).text() ); } else { $previewData.find( 'p.last-order' ).show(); $previewData.find( 'p.order-search' ).hide(); $previewData.find( 'input[name="preview-order-search"]' ).removeClass( 'active' ).val( '' ); $previewData.find( '#preview-order-search-results' ).hide(); $previewData.find( 'img.preview-order-search-clear' ).hide(); // remove the clear button resetOrderId() // force order ID reset triggerPreview(); // trigger preview } } ); // Preview on page load triggerPreview(); // Custom trigger to signify settings have changed (will show save button and refresh preview) $( document ).on( 'wpo-wcpdf-settings-changed', function( event, delay ) { showSaveBtn(); triggerPreview( delay ); } ); // Custom trigger to refresh preview $( document ).on( 'wpo-wcpdf-refresh-preview wpo_wcpdf_refresh_preview', function( event, delay ) { triggerPreview( delay ); } ); // Preview on user click in search result $( document ).on( 'click', '#preview-order-search-results a', function( event ) { event.preventDefault(); $( '.preview-document .order-search-label').text( '#' + $( this ).data( 'order_id' ) ); $previewOrderIdInput.val( $( this ).data( 'order_id' ) ).trigger( 'change' ); $( this ).closest( 'div' ).hide(); // hide results div $( this ).closest( 'div' ).children( 'a' ).remove(); // remove all results triggerPreview(); } ); // Check for settings change $( document ).on( 'keyup paste', '#wpo-wcpdf-settings input, #wpo-wcpdf-settings textarea', settingsChanged ); $( document ).on( 'change', '#wpo-wcpdf-settings input[type="checkbox"], #wpo-wcpdf-settings input[type="radio"], #wpo-wcpdf-settings select', function( event ) { if ( 'shop_address_country' === event.target.id || ! event.isTrigger ) { // exclude programmatic triggers that aren't actually changing anything settingsChanged( event ); } } ); $( document ).on( 'select2:select select2:unselect', '#wpo-wcpdf-settings select.wc-enhanced-select', settingsChanged ); $( document.body ).on( 'wpo-wcpdf-media-upload-setting-updated', settingsChanged ); $( document ).on( 'click', '.wpo_remove_image_button, #wpo-wcpdf-settings .remove-requirement', settingsChanged ); // On Multilingual if ( $( '#wpo_wcpdf_settings_general-shop_address_country-translations' ).length > 0 ) { $( '#wpo-wcpdf-settings select[name^="wpo_wcpdf_settings_general[shop_address_country]"]' ).each( function() { const $select = $( this ); if ( $select.val() ) { shopCountryChanged( $select ); } } ); } function settingsChanged( event, previewDelay ) { if ( 'shop_address_country' === event.target.id ) { shopCountryChanged( $( event.target ) ); } // Show secondary save button showSaveBtn(); // Check if preview needs to reload and with what delay let $element = $( event.target ); if ( ! settingIsExcludedForPreview( $element.attr('name') ) ) { if ( $element.hasClass( 'remove-requirement' ) || $element.attr('id') == 'disable_for' ) { return; } if ( $.inArray( event.type, ['keyup', 'paste'] ) !== -1 ) { if ( $element.is( 'input[type="checkbox"], select' ) ) { return; } else { previewDelay = event.type == 'keyup' ? 1000 : 0; } } triggerPreview( previewDelay ); } } function shopCountryChanged( $countryField ) { const selectedCountry = $countryField.val(); const $form = $countryField.closest( 'form' ); // Get the language key const nameMatch = $countryField.attr( 'name' ) .match( /\[shop_address_country]\[(.*?)\]/ ); // 'pt-pt', 'default', etc. const lang = nameMatch ? nameMatch[1] : 'default'; // Find the matching state field for that language const $state = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` ); // Keep the original button lookup, but relative to $state const $state_sync_button = $state .closest( '.wpo-wcpdf-input-wrapper' ) .find( '#shop_address_state_action' ); // Clear previous states $state.empty().prop( 'disabled', true ); $state_sync_button.prop( 'disabled', true ); // Temporary loading option $state.append( $( '', { value: '', text: wpo_wcpdf_admin.shop_country_changed_messages.loading } ) ); return $.ajax( { url: wpo_wcpdf_admin.ajaxurl, type: 'POST', dataType: 'json', data: { action: 'wcpdf_get_country_states', country: selectedCountry, security: wpo_wcpdf_admin.nonce, }, success: function( response ) { $state.empty(); const states = response.data?.states; const selected = response.data?.selected; if ( response.success && states && Object.keys( states ).length > 0 ) { $.each( states, function( code, name ) { $state.append( $( '', { value: code, text: name, selected: code === selected } ) ); } ); $state.prop( 'disabled', false ); $state_sync_button.prop( 'disabled', false ); } else { $state.append( $( '', { value: '', text: wpo_wcpdf_admin.shop_country_changed_messages.empty } ) ); } triggerPreview(); }, error: function() { $state.empty().append( $( '', { value: '', text: wpo_wcpdf_admin.shop_country_changed_messages.error } ) ); triggerPreview(); } } ); } function showSaveBtn( event ) { $( '.preview-data-wrapper .save-settings p' ).css( 'margin-right', '0' ); } // Submit settings form when clicking on secondary save button $( document.body ).on( 'click', '.preview-data-wrapper .save-settings p input', function( event ) { $( '#wpo-wcpdf-settings input#submit' ).trigger( 'click' ); } ); // Trigger the Preview function triggerPreview( timeoutDuration = 0 ) { $previewStates = $( '#wpo-wcpdf-preview-wrapper' ).data( 'preview-states' ); // Check if preview is disabled and return if ( 'undefined' === $previewStates || 1 === $previewStates ) { return; } timeoutDuration = typeof timeoutDuration == 'number' ? timeoutDuration : 0; loadPreviewData(); clearTimeout( previewTimeout ); previewTimeout = setTimeout( function() { ajaxLoadPreview() }, timeoutDuration ); } // Settings excluded from trigger the Preview function settingIsExcludedForPreview( settingName ) { let excluded = false; if ( ! settingName ) { return excluded; } let nameKey = settingName.includes( '[' ) ? settingName.match(/\[(.*?)\]/)[1] : settingName; if ( $.inArray( nameKey, wpo_wcpdf_admin.preview_excluded_settings ) !== -1 ) { excluded = true; } return excluded; } // Clear preview order search results/input $( document ).on( 'click', 'img.preview-order-search-clear', function( event ) { event.preventDefault(); $( this ).closest( 'div' ).find( 'input#preview-order-search' ).val( '' ); $( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).children( 'a' ).remove(); // remove previous results $( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).children( '.error' ).remove(); // remove previous errors $( this ).closest( '.preview-data' ).find( '#preview-order-search-results' ).hide(); $( this ).hide(); } ); // Trigger preview on document selection and change the document type input with the new value $( '#wpo-wcpdf-preview-wrapper ul.preview-data-option-list li' ).on( 'click', function() { let inputName = $( this ).closest( 'ul' ).data( 'input-name' ); let $input = $( '#wpo-wcpdf-preview-wrapper :input[name='+inputName+']'); $input.val( $( this ).data( 'value' ) ).trigger( 'change' ); } ); // Detect document type input changes and apply the same document title to the document selector $previewDocumentTypeInput.on( 'change', function() { let inputValue = $( this ).val(); if ( inputValue.length ) { let inputName = $( this ).attr( 'name' ); let $ul = $( '#wpo-wcpdf-preview-wrapper ul.preview-data-option-list[data-input-name='+inputName+']' ); let $li = $ul.find( 'li[data-value='+inputValue+']' ); $ul.parent().find( '.current-label' ).text( $li.text() ); triggerPreview(); } } ).trigger( 'change' ); // Detect order ID input changes $previewOrderIdInput.on( 'change', function() { triggerPreview(); } ).trigger( 'change' ); // Load the Preview with AJAX function ajaxLoadPreview() { console.log( 'Loading preview...' ); let worker = wpo_wcpdf_admin.pdfjs_worker; let canvasId = 'preview-canvas'; let data = { action: 'wpo_wcpdf_preview', security: previewNonce, order_id: previewOrderId, document_type: previewDocumentType, output_format: previewOutputFormat, data: previewSettingsFormData, }; // remove previous error notices $preview.children( '.notice' ).remove(); // block ui $preview.block( { message: null, overlayCSS: { background: '#fff', opacity: 0.6 } } ); previewXhr = $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, beforeSend: function( jqXHR, settings ) { if ( previewXhr != null ) { previewXhr.abort(); } }, success: function( response, textStatus, jqXHR ) { if ( response.data.error ) { $( '#' + canvasId ).remove(); $preview.append( '' + response.data.error + '' ); } else if ( response.data.preview_data && response.data.output_format ) { $( '#' + canvasId ).remove(); switch ( response.data.output_format ) { default: case 'pdf': $preview.append( '' ); renderPdf( worker, canvasId, response.data.preview_data ); break; case 'xml': { const rawXml = response.data.preview_data; // pretty-print xmlns declarations: const pretty = rawXml.replace( /\s+(xmlns(?::[\w.-]+)?=)/g, '\n $1' ); // build safely const $code = $( '', { class: 'language-xml' } ).text( pretty ); $preview.empty().append( $( '' ).append( $code ) ); // highlight just this element Prism.highlightElement( $code[0] ); break; } } } $preview.unblock(); }, error: function( jqXHR, textStatus, errorThrown ) { if ( textStatus != 'abort' ) { let errorMessage = jqXHR.status + ': ' + jqXHR.statusText $( '#' + canvasId ).remove(); $preview.append( '' + errorMessage + '' ); $preview.unblock(); } }, } ); } // pdf_js (third party library code) function renderPdf( worker, canvasId, pdfData ) { // atob() is used to convert base64 encoded PDF to binary-like data. // (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding.) pdfData = window.atob( pdfData ); // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = worker; // Using DocumentInitParameters object to load binary data. let loadingTask = pdfjsLib.getDocument( { data: pdfData } ); loadingTask.promise.then( function( pdf ) { // Fetch the first page let pageNumber = 1; pdf.getPage( pageNumber ).then( function( page ) { let scale = 2; let viewport = page.getViewport( { scale: scale } ); // Prepare canvas using PDF page dimensions let canvas = document.getElementById( canvasId ); let context = canvas.getContext( '2d' ); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context let renderContext = { canvasContext: context, viewport: viewport }; let renderTask = page.render( renderContext ); renderTask.promise.then( function() { // page rendered } ); } ); }, function( reason ) { // PDF loading error console.error( reason ); } ); } // Preview on user input $( '#preview-order-search' ).on( 'keyup paste', function( event ) { let $elem = $( this ); $elem.addClass( 'ajax-waiting' ); let duration = event.type == 'keyup' ? 1000 : 0; loadPreviewData(); clearTimeout( previewSearchTimeout ); previewSearchTimeout = setTimeout( function() { previewOrderSearch( $elem ) }, duration ); } ); // Preview order search function previewOrderSearch( $elem ) { let $div = $elem.closest( '.preview-data' ).find( '#preview-order-search-results' ); let value = $elem.val(); let nonce = $elem.data( 'nonce' ); let action = 'wpo_wcpdf_preview_order_search'; let data = { security: nonce, action: action, search: value, document_type: previewDocumentType, }; $div.parent().find( 'img.preview-order-search-clear' ).hide(); // hide the clear button $div.children( '.error' ).remove(); // remove previous errors $div.children( 'a' ).remove(); // remove previous results $div.hide(); // hide search results $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, success: function( response ) { if ( response.data ) { if ( response.data.error ) { $div.append( ''+response.data.error+'' ); $div.show(); } else { $.each( response.data, function( i, item ) { let firstLine = '#'+item.order_number+' - '+item.billing_first_name+' '+item.billing_last_name; if ( item.billing_company.length > 0 ) { firstLine = firstLine+', '+item.billing_company; } let secondLine = ''+item.date_created+''+item.total+''; $div.append( firstLine+secondLine ); $div.show(); } ); } } $elem.removeClass( 'ajax-waiting' ); $elem.closest( 'div' ).find( 'img.preview-order-search-clear' ).show(); } } ); } //----------> /Preview <----------// //----------> Settings Accordion <----------// function settingsAccordion() { // Get current tab. const params = new URLSearchParams( window.location.search ); const allowedTabs = [ 'general', 'documents', 'debug' ]; const tab = params.get( 'tab' ) || 'general'; if ( ! allowedTabs.includes( tab ) ) { return; } const tabsMainCategory = { general : 'display', documents : 'general', debug : 'filesystem_access' // Default open section for Advanced/Debug tab }; const sections = $( '.settings_category h2' ); if ( sections.length === 0 ) { return; // No sections found } // Accessibility attributes for accordion headers and panels sections.each( function ( index ) { const $header = $( this ); const $panel = $header.next( '.form-table' ); const $category = $header.parent( '.settings_category' ); const idBase = $category.attr( 'id' ) || $header.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; // Ensure header has an id and compute explicit ids if ( ! $header.attr( 'id' ) ) { $header.attr( 'id', `${idBase}_header` ); } const headerElementId = $header.attr( 'id' ); const panelId = `${idBase}_panel`; $header.attr( { 'role': 'button', 'tabindex': 0, 'aria-controls': panelId } ); $panel.attr( { 'id': panelId, 'role': 'region', 'aria-labelledby': headerElementId } ); } ); // Initialize accordion state sections.each( function ( index ) { const $header = $( this ); const $category = $header.parent( '.settings_category' ); const categoryId = $category.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; const $panel = $header.next( '.form-table' ); // Check localStorage for saved state const stored = localStorage.getItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}` ); let shouldOpen = false; if ( stored !== null ) { // User has previously interacted with this section - use saved state shouldOpen = stored === 'true'; } else if ( tabsMainCategory[ tab ] && categoryId === tabsMainCategory[ tab ] ) { // First visit - open the default main category for this tab shouldOpen = true; } // else: keep collapsed (shouldOpen = false) // Set initial state if ( shouldOpen ) { $header.addClass( 'active' ).attr( 'aria-expanded', true ); $panel.show().attr( 'aria-hidden', 'false' ); } else { $header.removeClass( 'active' ).attr( 'aria-expanded', false ); $panel.hide().attr( 'aria-hidden', 'true' ); } } ); // Toggle section on click function toggleSection( header ) { const $header = $( header ); const categoryId = $header.parent( '.settings_category' ).attr( 'id' ); const $panel = $header.next( '.form-table' ); const willOpen = ! $panel.is( ':visible' ); $header.toggleClass( 'active', willOpen ).attr( 'aria-expanded', willOpen ); $panel.stop( true, false ).slideToggle( { duration: 300, easing: 'swing', complete: function () { const isVisible = $( this ).is( ':visible' ); $( this ).attr( 'aria-hidden', isVisible ? 'false' : 'true' ); if ( categoryId ) { localStorage.setItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}`, isVisible ); } } } ); } // Bind click events sections.off( 'click' ).on( 'click', function () { toggleSection( this ); } ); // Keyboard accessibility sections.off( 'keydown' ).on( 'keydown', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' ) { e.preventDefault(); toggleSection( this ); } } ); } // Initialize accordion settingsAccordion(); //----------> /Settings Accordion <----------// //----------> Conditional Visibility <----------// const bound = new Set(); $( '[data-show_for_option_name]' ).each( function () { const opt = $( this ).data( 'show_for_option_name' ); if ( bound.has( opt ) ) { return; } $( document ).on( 'change', `[name="${opt}"], [name="${opt}[]"]`, toggle_conditional_visibility ); $( `[name="${opt}"], [name="${opt}[]"]` ).each( function () { toggle_conditional_visibility( { target: this } ); } ); bound.add( opt ); } ); function toggle_conditional_visibility( e ) { const $this = $( e.target ); let name = $this.prop( 'name' ).replace( '[]', '' ); // normalize multiselect let value = $this.val(); let checkbox = false; if ( $this.is( ':checkbox' ) ) { value = $this.is( ':checked' ); checkbox = true; } $( "[data-show_for_option_name='" + name + "']" ).each( function() { let show = false; let show_for = $( this ).data( 'show_for_option_values' ); let keep_value = $( this ).data( 'keep_current_value' ); if ( checkbox ) { show = value; // for checkboxes, checked = show } else if ( Array.isArray( value ) ) { // Multiselect show = value.some( item => show_for.includes( item ) ); } else { show = show_for.includes( value ); } let $row = $( this ).closest( 'tr' ); if ( show ) { $row.show(); if ( checkbox ) { $row.find( ':input[type=checkbox]' ).val( '1' ); } } else { $row.hide() .find( ':input' ).each( function () { const $input = $( this ); // Don't reset value if ( keep_value ) { return; } // Reset the input value if ( $input.is( 'select' ) ) { if ( $input.prop( 'multiple' ) ) { $input.val( [] ); } else { $input.prop( 'selectedIndex', 0 ); } } else if ( $input.is( ':checkbox' ) ) { $input.prop( 'checked', false ); } else { $input.val( '' ); } $input.trigger( 'change' ); } ); } } ); } //----------> /Conditional Visibility <----------// //----------> Sync Address <----------// $( '#wpo-wcpdf-settings .sync-address' ).on( 'click', function( event ) { event.preventDefault(); const $button = $( this ); const $form = $( this ).closest('form'); const $icon = $button.find( 'span.dashicons' ); const $tooltip = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( '.sync-tooltip' ); let $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'input' ); if ( $field.length === 0 ) { $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'select' ); } // Rotate the icon to indicate processing. $icon.toggleClass( 'rotate' ); $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: { action: 'wpo_wcpdf_sync_address', security: wpo_wcpdf_admin.nonce, address_field: $field.attr( 'id' ), }, success: function( response ) { if ( response.success && response.data.value && '' !== response.data.value.trim() ) { if ( 'shop_address_country' === $field.attr( 'id' ) ) { const country_state = response.data.value.split( ':' ); $field.val( country_state[0] ); // Update states if the country changed. shopCountryChanged( $field ).done( function() { const matches = $field.attr( 'name' ).match( /\[([^\]]+)\]/g ); // matches all bracket parts const lang = matches ? matches[ matches.length - 1 ].replace( /[\[\]]/g, '' ) : 'default'; const $stateField = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` ); // Update the selected state. if ( $stateField.length !== 0 ) { $stateField.val( country_state[1] ); } } ); } else { $field.val( response.data.value ); } triggerPreview(); } else if ( ! response.success && response.data.message && '' !== response.data.message.trim() ) { $tooltip.text( response.data.message ).addClass( 'visible' ); setTimeout( function() { $tooltip.removeClass( 'visible' ); }, 3000 ); } }, complete: function() { // Reset the icon rotation. $icon.toggleClass( 'rotate' ); } } ); } ); //----------> /Sync Address <----------// } );
' + response.data.error + '
safely const $code = $( '', { class: 'language-xml' } ).text( pretty ); $preview.empty().append( $( '' ).append( $code ) ); // highlight just this element Prism.highlightElement( $code[0] ); break; } } } $preview.unblock(); }, error: function( jqXHR, textStatus, errorThrown ) { if ( textStatus != 'abort' ) { let errorMessage = jqXHR.status + ': ' + jqXHR.statusText $( '#' + canvasId ).remove(); $preview.append( '' + errorMessage + '' ); $preview.unblock(); } }, } ); } // pdf_js (third party library code) function renderPdf( worker, canvasId, pdfData ) { // atob() is used to convert base64 encoded PDF to binary-like data. // (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding.) pdfData = window.atob( pdfData ); // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = worker; // Using DocumentInitParameters object to load binary data. let loadingTask = pdfjsLib.getDocument( { data: pdfData } ); loadingTask.promise.then( function( pdf ) { // Fetch the first page let pageNumber = 1; pdf.getPage( pageNumber ).then( function( page ) { let scale = 2; let viewport = page.getViewport( { scale: scale } ); // Prepare canvas using PDF page dimensions let canvas = document.getElementById( canvasId ); let context = canvas.getContext( '2d' ); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context let renderContext = { canvasContext: context, viewport: viewport }; let renderTask = page.render( renderContext ); renderTask.promise.then( function() { // page rendered } ); } ); }, function( reason ) { // PDF loading error console.error( reason ); } ); } // Preview on user input $( '#preview-order-search' ).on( 'keyup paste', function( event ) { let $elem = $( this ); $elem.addClass( 'ajax-waiting' ); let duration = event.type == 'keyup' ? 1000 : 0; loadPreviewData(); clearTimeout( previewSearchTimeout ); previewSearchTimeout = setTimeout( function() { previewOrderSearch( $elem ) }, duration ); } ); // Preview order search function previewOrderSearch( $elem ) { let $div = $elem.closest( '.preview-data' ).find( '#preview-order-search-results' ); let value = $elem.val(); let nonce = $elem.data( 'nonce' ); let action = 'wpo_wcpdf_preview_order_search'; let data = { security: nonce, action: action, search: value, document_type: previewDocumentType, }; $div.parent().find( 'img.preview-order-search-clear' ).hide(); // hide the clear button $div.children( '.error' ).remove(); // remove previous errors $div.children( 'a' ).remove(); // remove previous results $div.hide(); // hide search results $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, success: function( response ) { if ( response.data ) { if ( response.data.error ) { $div.append( ''+response.data.error+'' ); $div.show(); } else { $.each( response.data, function( i, item ) { let firstLine = '#'+item.order_number+' - '+item.billing_first_name+' '+item.billing_last_name; if ( item.billing_company.length > 0 ) { firstLine = firstLine+', '+item.billing_company; } let secondLine = ''+item.date_created+''+item.total+''; $div.append( firstLine+secondLine ); $div.show(); } ); } } $elem.removeClass( 'ajax-waiting' ); $elem.closest( 'div' ).find( 'img.preview-order-search-clear' ).show(); } } ); } //----------> /Preview <----------// //----------> Settings Accordion <----------// function settingsAccordion() { // Get current tab. const params = new URLSearchParams( window.location.search ); const allowedTabs = [ 'general', 'documents', 'debug' ]; const tab = params.get( 'tab' ) || 'general'; if ( ! allowedTabs.includes( tab ) ) { return; } const tabsMainCategory = { general : 'display', documents : 'general', debug : 'filesystem_access' // Default open section for Advanced/Debug tab }; const sections = $( '.settings_category h2' ); if ( sections.length === 0 ) { return; // No sections found } // Accessibility attributes for accordion headers and panels sections.each( function ( index ) { const $header = $( this ); const $panel = $header.next( '.form-table' ); const $category = $header.parent( '.settings_category' ); const idBase = $category.attr( 'id' ) || $header.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; // Ensure header has an id and compute explicit ids if ( ! $header.attr( 'id' ) ) { $header.attr( 'id', `${idBase}_header` ); } const headerElementId = $header.attr( 'id' ); const panelId = `${idBase}_panel`; $header.attr( { 'role': 'button', 'tabindex': 0, 'aria-controls': panelId } ); $panel.attr( { 'id': panelId, 'role': 'region', 'aria-labelledby': headerElementId } ); } ); // Initialize accordion state sections.each( function ( index ) { const $header = $( this ); const $category = $header.parent( '.settings_category' ); const categoryId = $category.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; const $panel = $header.next( '.form-table' ); // Check localStorage for saved state const stored = localStorage.getItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}` ); let shouldOpen = false; if ( stored !== null ) { // User has previously interacted with this section - use saved state shouldOpen = stored === 'true'; } else if ( tabsMainCategory[ tab ] && categoryId === tabsMainCategory[ tab ] ) { // First visit - open the default main category for this tab shouldOpen = true; } // else: keep collapsed (shouldOpen = false) // Set initial state if ( shouldOpen ) { $header.addClass( 'active' ).attr( 'aria-expanded', true ); $panel.show().attr( 'aria-hidden', 'false' ); } else { $header.removeClass( 'active' ).attr( 'aria-expanded', false ); $panel.hide().attr( 'aria-hidden', 'true' ); } } ); // Toggle section on click function toggleSection( header ) { const $header = $( header ); const categoryId = $header.parent( '.settings_category' ).attr( 'id' ); const $panel = $header.next( '.form-table' ); const willOpen = ! $panel.is( ':visible' ); $header.toggleClass( 'active', willOpen ).attr( 'aria-expanded', willOpen ); $panel.stop( true, false ).slideToggle( { duration: 300, easing: 'swing', complete: function () { const isVisible = $( this ).is( ':visible' ); $( this ).attr( 'aria-hidden', isVisible ? 'false' : 'true' ); if ( categoryId ) { localStorage.setItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}`, isVisible ); } } } ); } // Bind click events sections.off( 'click' ).on( 'click', function () { toggleSection( this ); } ); // Keyboard accessibility sections.off( 'keydown' ).on( 'keydown', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' ) { e.preventDefault(); toggleSection( this ); } } ); } // Initialize accordion settingsAccordion(); //----------> /Settings Accordion <----------// //----------> Conditional Visibility <----------// const bound = new Set(); $( '[data-show_for_option_name]' ).each( function () { const opt = $( this ).data( 'show_for_option_name' ); if ( bound.has( opt ) ) { return; } $( document ).on( 'change', `[name="${opt}"], [name="${opt}[]"]`, toggle_conditional_visibility ); $( `[name="${opt}"], [name="${opt}[]"]` ).each( function () { toggle_conditional_visibility( { target: this } ); } ); bound.add( opt ); } ); function toggle_conditional_visibility( e ) { const $this = $( e.target ); let name = $this.prop( 'name' ).replace( '[]', '' ); // normalize multiselect let value = $this.val(); let checkbox = false; if ( $this.is( ':checkbox' ) ) { value = $this.is( ':checked' ); checkbox = true; } $( "[data-show_for_option_name='" + name + "']" ).each( function() { let show = false; let show_for = $( this ).data( 'show_for_option_values' ); let keep_value = $( this ).data( 'keep_current_value' ); if ( checkbox ) { show = value; // for checkboxes, checked = show } else if ( Array.isArray( value ) ) { // Multiselect show = value.some( item => show_for.includes( item ) ); } else { show = show_for.includes( value ); } let $row = $( this ).closest( 'tr' ); if ( show ) { $row.show(); if ( checkbox ) { $row.find( ':input[type=checkbox]' ).val( '1' ); } } else { $row.hide() .find( ':input' ).each( function () { const $input = $( this ); // Don't reset value if ( keep_value ) { return; } // Reset the input value if ( $input.is( 'select' ) ) { if ( $input.prop( 'multiple' ) ) { $input.val( [] ); } else { $input.prop( 'selectedIndex', 0 ); } } else if ( $input.is( ':checkbox' ) ) { $input.prop( 'checked', false ); } else { $input.val( '' ); } $input.trigger( 'change' ); } ); } } ); } //----------> /Conditional Visibility <----------// //----------> Sync Address <----------// $( '#wpo-wcpdf-settings .sync-address' ).on( 'click', function( event ) { event.preventDefault(); const $button = $( this ); const $form = $( this ).closest('form'); const $icon = $button.find( 'span.dashicons' ); const $tooltip = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( '.sync-tooltip' ); let $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'input' ); if ( $field.length === 0 ) { $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'select' ); } // Rotate the icon to indicate processing. $icon.toggleClass( 'rotate' ); $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: { action: 'wpo_wcpdf_sync_address', security: wpo_wcpdf_admin.nonce, address_field: $field.attr( 'id' ), }, success: function( response ) { if ( response.success && response.data.value && '' !== response.data.value.trim() ) { if ( 'shop_address_country' === $field.attr( 'id' ) ) { const country_state = response.data.value.split( ':' ); $field.val( country_state[0] ); // Update states if the country changed. shopCountryChanged( $field ).done( function() { const matches = $field.attr( 'name' ).match( /\[([^\]]+)\]/g ); // matches all bracket parts const lang = matches ? matches[ matches.length - 1 ].replace( /[\[\]]/g, '' ) : 'default'; const $stateField = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` ); // Update the selected state. if ( $stateField.length !== 0 ) { $stateField.val( country_state[1] ); } } ); } else { $field.val( response.data.value ); } triggerPreview(); } else if ( ! response.success && response.data.message && '' !== response.data.message.trim() ) { $tooltip.text( response.data.message ).addClass( 'visible' ); setTimeout( function() { $tooltip.removeClass( 'visible' ); }, 3000 ); } }, complete: function() { // Reset the icon rotation. $icon.toggleClass( 'rotate' ); } } ); } ); //----------> /Sync Address <----------// } );
', { class: 'language-xml' } ).text( pretty ); $preview.empty().append( $( '' ).append( $code ) ); // highlight just this element Prism.highlightElement( $code[0] ); break; } } } $preview.unblock(); }, error: function( jqXHR, textStatus, errorThrown ) { if ( textStatus != 'abort' ) { let errorMessage = jqXHR.status + ': ' + jqXHR.statusText $( '#' + canvasId ).remove(); $preview.append( '' + errorMessage + '' ); $preview.unblock(); } }, } ); } // pdf_js (third party library code) function renderPdf( worker, canvasId, pdfData ) { // atob() is used to convert base64 encoded PDF to binary-like data. // (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding.) pdfData = window.atob( pdfData ); // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = worker; // Using DocumentInitParameters object to load binary data. let loadingTask = pdfjsLib.getDocument( { data: pdfData } ); loadingTask.promise.then( function( pdf ) { // Fetch the first page let pageNumber = 1; pdf.getPage( pageNumber ).then( function( page ) { let scale = 2; let viewport = page.getViewport( { scale: scale } ); // Prepare canvas using PDF page dimensions let canvas = document.getElementById( canvasId ); let context = canvas.getContext( '2d' ); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context let renderContext = { canvasContext: context, viewport: viewport }; let renderTask = page.render( renderContext ); renderTask.promise.then( function() { // page rendered } ); } ); }, function( reason ) { // PDF loading error console.error( reason ); } ); } // Preview on user input $( '#preview-order-search' ).on( 'keyup paste', function( event ) { let $elem = $( this ); $elem.addClass( 'ajax-waiting' ); let duration = event.type == 'keyup' ? 1000 : 0; loadPreviewData(); clearTimeout( previewSearchTimeout ); previewSearchTimeout = setTimeout( function() { previewOrderSearch( $elem ) }, duration ); } ); // Preview order search function previewOrderSearch( $elem ) { let $div = $elem.closest( '.preview-data' ).find( '#preview-order-search-results' ); let value = $elem.val(); let nonce = $elem.data( 'nonce' ); let action = 'wpo_wcpdf_preview_order_search'; let data = { security: nonce, action: action, search: value, document_type: previewDocumentType, }; $div.parent().find( 'img.preview-order-search-clear' ).hide(); // hide the clear button $div.children( '.error' ).remove(); // remove previous errors $div.children( 'a' ).remove(); // remove previous results $div.hide(); // hide search results $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, success: function( response ) { if ( response.data ) { if ( response.data.error ) { $div.append( ''+response.data.error+'' ); $div.show(); } else { $.each( response.data, function( i, item ) { let firstLine = '#'+item.order_number+' - '+item.billing_first_name+' '+item.billing_last_name; if ( item.billing_company.length > 0 ) { firstLine = firstLine+', '+item.billing_company; } let secondLine = ''+item.date_created+''+item.total+''; $div.append( firstLine+secondLine ); $div.show(); } ); } } $elem.removeClass( 'ajax-waiting' ); $elem.closest( 'div' ).find( 'img.preview-order-search-clear' ).show(); } } ); } //----------> /Preview <----------// //----------> Settings Accordion <----------// function settingsAccordion() { // Get current tab. const params = new URLSearchParams( window.location.search ); const allowedTabs = [ 'general', 'documents', 'debug' ]; const tab = params.get( 'tab' ) || 'general'; if ( ! allowedTabs.includes( tab ) ) { return; } const tabsMainCategory = { general : 'display', documents : 'general', debug : 'filesystem_access' // Default open section for Advanced/Debug tab }; const sections = $( '.settings_category h2' ); if ( sections.length === 0 ) { return; // No sections found } // Accessibility attributes for accordion headers and panels sections.each( function ( index ) { const $header = $( this ); const $panel = $header.next( '.form-table' ); const $category = $header.parent( '.settings_category' ); const idBase = $category.attr( 'id' ) || $header.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; // Ensure header has an id and compute explicit ids if ( ! $header.attr( 'id' ) ) { $header.attr( 'id', `${idBase}_header` ); } const headerElementId = $header.attr( 'id' ); const panelId = `${idBase}_panel`; $header.attr( { 'role': 'button', 'tabindex': 0, 'aria-controls': panelId } ); $panel.attr( { 'id': panelId, 'role': 'region', 'aria-labelledby': headerElementId } ); } ); // Initialize accordion state sections.each( function ( index ) { const $header = $( this ); const $category = $header.parent( '.settings_category' ); const categoryId = $category.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; const $panel = $header.next( '.form-table' ); // Check localStorage for saved state const stored = localStorage.getItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}` ); let shouldOpen = false; if ( stored !== null ) { // User has previously interacted with this section - use saved state shouldOpen = stored === 'true'; } else if ( tabsMainCategory[ tab ] && categoryId === tabsMainCategory[ tab ] ) { // First visit - open the default main category for this tab shouldOpen = true; } // else: keep collapsed (shouldOpen = false) // Set initial state if ( shouldOpen ) { $header.addClass( 'active' ).attr( 'aria-expanded', true ); $panel.show().attr( 'aria-hidden', 'false' ); } else { $header.removeClass( 'active' ).attr( 'aria-expanded', false ); $panel.hide().attr( 'aria-hidden', 'true' ); } } ); // Toggle section on click function toggleSection( header ) { const $header = $( header ); const categoryId = $header.parent( '.settings_category' ).attr( 'id' ); const $panel = $header.next( '.form-table' ); const willOpen = ! $panel.is( ':visible' ); $header.toggleClass( 'active', willOpen ).attr( 'aria-expanded', willOpen ); $panel.stop( true, false ).slideToggle( { duration: 300, easing: 'swing', complete: function () { const isVisible = $( this ).is( ':visible' ); $( this ).attr( 'aria-hidden', isVisible ? 'false' : 'true' ); if ( categoryId ) { localStorage.setItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}`, isVisible ); } } } ); } // Bind click events sections.off( 'click' ).on( 'click', function () { toggleSection( this ); } ); // Keyboard accessibility sections.off( 'keydown' ).on( 'keydown', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' ) { e.preventDefault(); toggleSection( this ); } } ); } // Initialize accordion settingsAccordion(); //----------> /Settings Accordion <----------// //----------> Conditional Visibility <----------// const bound = new Set(); $( '[data-show_for_option_name]' ).each( function () { const opt = $( this ).data( 'show_for_option_name' ); if ( bound.has( opt ) ) { return; } $( document ).on( 'change', `[name="${opt}"], [name="${opt}[]"]`, toggle_conditional_visibility ); $( `[name="${opt}"], [name="${opt}[]"]` ).each( function () { toggle_conditional_visibility( { target: this } ); } ); bound.add( opt ); } ); function toggle_conditional_visibility( e ) { const $this = $( e.target ); let name = $this.prop( 'name' ).replace( '[]', '' ); // normalize multiselect let value = $this.val(); let checkbox = false; if ( $this.is( ':checkbox' ) ) { value = $this.is( ':checked' ); checkbox = true; } $( "[data-show_for_option_name='" + name + "']" ).each( function() { let show = false; let show_for = $( this ).data( 'show_for_option_values' ); let keep_value = $( this ).data( 'keep_current_value' ); if ( checkbox ) { show = value; // for checkboxes, checked = show } else if ( Array.isArray( value ) ) { // Multiselect show = value.some( item => show_for.includes( item ) ); } else { show = show_for.includes( value ); } let $row = $( this ).closest( 'tr' ); if ( show ) { $row.show(); if ( checkbox ) { $row.find( ':input[type=checkbox]' ).val( '1' ); } } else { $row.hide() .find( ':input' ).each( function () { const $input = $( this ); // Don't reset value if ( keep_value ) { return; } // Reset the input value if ( $input.is( 'select' ) ) { if ( $input.prop( 'multiple' ) ) { $input.val( [] ); } else { $input.prop( 'selectedIndex', 0 ); } } else if ( $input.is( ':checkbox' ) ) { $input.prop( 'checked', false ); } else { $input.val( '' ); } $input.trigger( 'change' ); } ); } } ); } //----------> /Conditional Visibility <----------// //----------> Sync Address <----------// $( '#wpo-wcpdf-settings .sync-address' ).on( 'click', function( event ) { event.preventDefault(); const $button = $( this ); const $form = $( this ).closest('form'); const $icon = $button.find( 'span.dashicons' ); const $tooltip = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( '.sync-tooltip' ); let $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'input' ); if ( $field.length === 0 ) { $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'select' ); } // Rotate the icon to indicate processing. $icon.toggleClass( 'rotate' ); $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: { action: 'wpo_wcpdf_sync_address', security: wpo_wcpdf_admin.nonce, address_field: $field.attr( 'id' ), }, success: function( response ) { if ( response.success && response.data.value && '' !== response.data.value.trim() ) { if ( 'shop_address_country' === $field.attr( 'id' ) ) { const country_state = response.data.value.split( ':' ); $field.val( country_state[0] ); // Update states if the country changed. shopCountryChanged( $field ).done( function() { const matches = $field.attr( 'name' ).match( /\[([^\]]+)\]/g ); // matches all bracket parts const lang = matches ? matches[ matches.length - 1 ].replace( /[\[\]]/g, '' ) : 'default'; const $stateField = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` ); // Update the selected state. if ( $stateField.length !== 0 ) { $stateField.val( country_state[1] ); } } ); } else { $field.val( response.data.value ); } triggerPreview(); } else if ( ! response.success && response.data.message && '' !== response.data.message.trim() ) { $tooltip.text( response.data.message ).addClass( 'visible' ); setTimeout( function() { $tooltip.removeClass( 'visible' ); }, 3000 ); } }, complete: function() { // Reset the icon rotation. $icon.toggleClass( 'rotate' ); } } ); } ); //----------> /Sync Address <----------// } );
' ).append( $code ) ); // highlight just this element Prism.highlightElement( $code[0] ); break; } } } $preview.unblock(); }, error: function( jqXHR, textStatus, errorThrown ) { if ( textStatus != 'abort' ) { let errorMessage = jqXHR.status + ': ' + jqXHR.statusText $( '#' + canvasId ).remove(); $preview.append( '' + errorMessage + '' ); $preview.unblock(); } }, } ); } // pdf_js (third party library code) function renderPdf( worker, canvasId, pdfData ) { // atob() is used to convert base64 encoded PDF to binary-like data. // (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding.) pdfData = window.atob( pdfData ); // The workerSrc property shall be specified. pdfjsLib.GlobalWorkerOptions.workerSrc = worker; // Using DocumentInitParameters object to load binary data. let loadingTask = pdfjsLib.getDocument( { data: pdfData } ); loadingTask.promise.then( function( pdf ) { // Fetch the first page let pageNumber = 1; pdf.getPage( pageNumber ).then( function( page ) { let scale = 2; let viewport = page.getViewport( { scale: scale } ); // Prepare canvas using PDF page dimensions let canvas = document.getElementById( canvasId ); let context = canvas.getContext( '2d' ); canvas.height = viewport.height; canvas.width = viewport.width; // Render PDF page into canvas context let renderContext = { canvasContext: context, viewport: viewport }; let renderTask = page.render( renderContext ); renderTask.promise.then( function() { // page rendered } ); } ); }, function( reason ) { // PDF loading error console.error( reason ); } ); } // Preview on user input $( '#preview-order-search' ).on( 'keyup paste', function( event ) { let $elem = $( this ); $elem.addClass( 'ajax-waiting' ); let duration = event.type == 'keyup' ? 1000 : 0; loadPreviewData(); clearTimeout( previewSearchTimeout ); previewSearchTimeout = setTimeout( function() { previewOrderSearch( $elem ) }, duration ); } ); // Preview order search function previewOrderSearch( $elem ) { let $div = $elem.closest( '.preview-data' ).find( '#preview-order-search-results' ); let value = $elem.val(); let nonce = $elem.data( 'nonce' ); let action = 'wpo_wcpdf_preview_order_search'; let data = { security: nonce, action: action, search: value, document_type: previewDocumentType, }; $div.parent().find( 'img.preview-order-search-clear' ).hide(); // hide the clear button $div.children( '.error' ).remove(); // remove previous errors $div.children( 'a' ).remove(); // remove previous results $div.hide(); // hide search results $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: data, success: function( response ) { if ( response.data ) { if ( response.data.error ) { $div.append( ''+response.data.error+'' ); $div.show(); } else { $.each( response.data, function( i, item ) { let firstLine = '#'+item.order_number+' - '+item.billing_first_name+' '+item.billing_last_name; if ( item.billing_company.length > 0 ) { firstLine = firstLine+', '+item.billing_company; } let secondLine = ''+item.date_created+''+item.total+''; $div.append( firstLine+secondLine ); $div.show(); } ); } } $elem.removeClass( 'ajax-waiting' ); $elem.closest( 'div' ).find( 'img.preview-order-search-clear' ).show(); } } ); } //----------> /Preview <----------// //----------> Settings Accordion <----------// function settingsAccordion() { // Get current tab. const params = new URLSearchParams( window.location.search ); const allowedTabs = [ 'general', 'documents', 'debug' ]; const tab = params.get( 'tab' ) || 'general'; if ( ! allowedTabs.includes( tab ) ) { return; } const tabsMainCategory = { general : 'display', documents : 'general', debug : 'filesystem_access' // Default open section for Advanced/Debug tab }; const sections = $( '.settings_category h2' ); if ( sections.length === 0 ) { return; // No sections found } // Accessibility attributes for accordion headers and panels sections.each( function ( index ) { const $header = $( this ); const $panel = $header.next( '.form-table' ); const $category = $header.parent( '.settings_category' ); const idBase = $category.attr( 'id' ) || $header.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; // Ensure header has an id and compute explicit ids if ( ! $header.attr( 'id' ) ) { $header.attr( 'id', `${idBase}_header` ); } const headerElementId = $header.attr( 'id' ); const panelId = `${idBase}_panel`; $header.attr( { 'role': 'button', 'tabindex': 0, 'aria-controls': panelId } ); $panel.attr( { 'id': panelId, 'role': 'region', 'aria-labelledby': headerElementId } ); } ); // Initialize accordion state sections.each( function ( index ) { const $header = $( this ); const $category = $header.parent( '.settings_category' ); const categoryId = $category.attr( 'id' ) || `wcpdf_${tab}_section_${index}`; const $panel = $header.next( '.form-table' ); // Check localStorage for saved state const stored = localStorage.getItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}` ); let shouldOpen = false; if ( stored !== null ) { // User has previously interacted with this section - use saved state shouldOpen = stored === 'true'; } else if ( tabsMainCategory[ tab ] && categoryId === tabsMainCategory[ tab ] ) { // First visit - open the default main category for this tab shouldOpen = true; } // else: keep collapsed (shouldOpen = false) // Set initial state if ( shouldOpen ) { $header.addClass( 'active' ).attr( 'aria-expanded', true ); $panel.show().attr( 'aria-hidden', 'false' ); } else { $header.removeClass( 'active' ).attr( 'aria-expanded', false ); $panel.hide().attr( 'aria-hidden', 'true' ); } } ); // Toggle section on click function toggleSection( header ) { const $header = $( header ); const categoryId = $header.parent( '.settings_category' ).attr( 'id' ); const $panel = $header.next( '.form-table' ); const willOpen = ! $panel.is( ':visible' ); $header.toggleClass( 'active', willOpen ).attr( 'aria-expanded', willOpen ); $panel.stop( true, false ).slideToggle( { duration: 300, easing: 'swing', complete: function () { const isVisible = $( this ).is( ':visible' ); $( this ).attr( 'aria-hidden', isVisible ? 'false' : 'true' ); if ( categoryId ) { localStorage.setItem( `wcpdf_${tab}_settings_accordion_state_${categoryId}`, isVisible ); } } } ); } // Bind click events sections.off( 'click' ).on( 'click', function () { toggleSection( this ); } ); // Keyboard accessibility sections.off( 'keydown' ).on( 'keydown', function ( e ) { if ( e.key === 'Enter' || e.key === ' ' ) { e.preventDefault(); toggleSection( this ); } } ); } // Initialize accordion settingsAccordion(); //----------> /Settings Accordion <----------// //----------> Conditional Visibility <----------// const bound = new Set(); $( '[data-show_for_option_name]' ).each( function () { const opt = $( this ).data( 'show_for_option_name' ); if ( bound.has( opt ) ) { return; } $( document ).on( 'change', `[name="${opt}"], [name="${opt}[]"]`, toggle_conditional_visibility ); $( `[name="${opt}"], [name="${opt}[]"]` ).each( function () { toggle_conditional_visibility( { target: this } ); } ); bound.add( opt ); } ); function toggle_conditional_visibility( e ) { const $this = $( e.target ); let name = $this.prop( 'name' ).replace( '[]', '' ); // normalize multiselect let value = $this.val(); let checkbox = false; if ( $this.is( ':checkbox' ) ) { value = $this.is( ':checked' ); checkbox = true; } $( "[data-show_for_option_name='" + name + "']" ).each( function() { let show = false; let show_for = $( this ).data( 'show_for_option_values' ); let keep_value = $( this ).data( 'keep_current_value' ); if ( checkbox ) { show = value; // for checkboxes, checked = show } else if ( Array.isArray( value ) ) { // Multiselect show = value.some( item => show_for.includes( item ) ); } else { show = show_for.includes( value ); } let $row = $( this ).closest( 'tr' ); if ( show ) { $row.show(); if ( checkbox ) { $row.find( ':input[type=checkbox]' ).val( '1' ); } } else { $row.hide() .find( ':input' ).each( function () { const $input = $( this ); // Don't reset value if ( keep_value ) { return; } // Reset the input value if ( $input.is( 'select' ) ) { if ( $input.prop( 'multiple' ) ) { $input.val( [] ); } else { $input.prop( 'selectedIndex', 0 ); } } else if ( $input.is( ':checkbox' ) ) { $input.prop( 'checked', false ); } else { $input.val( '' ); } $input.trigger( 'change' ); } ); } } ); } //----------> /Conditional Visibility <----------// //----------> Sync Address <----------// $( '#wpo-wcpdf-settings .sync-address' ).on( 'click', function( event ) { event.preventDefault(); const $button = $( this ); const $form = $( this ).closest('form'); const $icon = $button.find( 'span.dashicons' ); const $tooltip = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( '.sync-tooltip' ); let $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'input' ); if ( $field.length === 0 ) { $field = $button.closest( '.wpo-wcpdf-input-wrapper' ).find( 'select' ); } // Rotate the icon to indicate processing. $icon.toggleClass( 'rotate' ); $.ajax( { type: 'POST', url: wpo_wcpdf_admin.ajaxurl, data: { action: 'wpo_wcpdf_sync_address', security: wpo_wcpdf_admin.nonce, address_field: $field.attr( 'id' ), }, success: function( response ) { if ( response.success && response.data.value && '' !== response.data.value.trim() ) { if ( 'shop_address_country' === $field.attr( 'id' ) ) { const country_state = response.data.value.split( ':' ); $field.val( country_state[0] ); // Update states if the country changed. shopCountryChanged( $field ).done( function() { const matches = $field.attr( 'name' ).match( /\[([^\]]+)\]/g ); // matches all bracket parts const lang = matches ? matches[ matches.length - 1 ].replace( /[\[\]]/g, '' ) : 'default'; const $stateField = $form.find( `select[name="wpo_wcpdf_settings_general[shop_address_state][${lang}]"]` ); // Update the selected state. if ( $stateField.length !== 0 ) { $stateField.val( country_state[1] ); } } ); } else { $field.val( response.data.value ); } triggerPreview(); } else if ( ! response.success && response.data.message && '' !== response.data.message.trim() ) { $tooltip.text( response.data.message ).addClass( 'visible' ); setTimeout( function() { $tooltip.removeClass( 'visible' ); }, 3000 ); } }, complete: function() { // Reset the icon rotation. $icon.toggleClass( 'rotate' ); } } ); } ); //----------> /Sync Address <----------// } );
' + errorMessage + '