/* global List */ 'use strict'; var WPMailSMTP = window.WPMailSMTP || {}; WPMailSMTP.Admin = WPMailSMTP.Admin || {}; /** * WP Mail SMTP Admin area Code Snippets module. * * @since 4.9.0 */ WPMailSMTP.Admin.CodeSnippets = WPMailSMTP.Admin.CodeSnippets || ( function( document, window, $ ) { /** * Public functions and properties. * * @since 4.9.0 * * @type {object} */ var app = { /** * List.js instance for the snippet grid. * * @since 4.9.0 * * @type {object} */ snippetSearch: null, /** * Start the engine. DOM is not ready yet, use only to init something. * * @since 4.9.0 */ init: function() { $( app.ready ); }, /** * DOM is fully loaded. * * @since 4.9.0 */ ready: function() { app.snippetSearch = new List( 'wp-mail-smtp-wpcode-snippets-list', { valueNames: [ 'wp-mail-smtp-wpcode-snippet-title' ], } ); app.events(); }, /** * Bind events. * * @since 4.9.0 */ events: function() { // Fallback overlay button installs WPCode directly. $( '.wp-mail-smtp-wpcode-fallback-install-plugin' ).on( 'click', app.onFallbackInstallClick ); // Card "Install Snippet" (WPCode absent) opens the install-plugin popup. $( '.wp-mail-smtp-wpcode-install-plugin' ).on( 'click', app.openInstallPluginPopup ); // Card "Install Snippet" (WPCode installed but inactive) activates WPCode, then installs. $( '.wp-mail-smtp-wpcode-activate-plugin' ).on( 'click', app.onActivatePluginClick ); // "View" opens the code-preview modal. $( '.wp-mail-smtp-wpcode-view-snippet' ).on( 'click', app.openViewSnippetModal ); // Active-state "Install Snippet" shows an installing state before navigating to WPCode. $( '.wp-mail-smtp-wpcode-install-snippet' ).on( 'click', app.installSnippet ); $( '#wp-mail-smtp-wpcode-snippet-search' ).on( 'keyup search', function() { app.searchSnippet( this ); } ); }, /** * POST to an admin-ajax action with the nonce attached. * * @since 4.9.0 * * @param {string} action admin-ajax action name. * @param {object} extra Action-specific fields merged into the request. * * @returns {object} The jQuery jqXHR promise. */ post: function( action, extra ) { var data = $.extend( { action: action, nonce: window.wp_mail_smtp.nonce, }, extra || {} ); return $.post( window.wp_mail_smtp.ajax_url, data ); }, /** * Enter the installing state: hide the badge/label and overlay a spinner * on the button (CSS keeps the button width). * * @since 4.9.0 * * @param {object} $label Badge or "installing" label element. * @param {object} $button Action button element. */ setInstalling: function( $label, $button ) { $label.addClass( 'wp-mail-smtp-wpcode-installing-in-progress' ).text( window.wp_mail_smtp_code_snippets.installing_text ); $button.addClass( 'wp-mail-smtp-btn-loading' ); }, /** * Leave the installing state (used when a flow fails and the UI stays put). * * @since 4.9.0 * * @param {object} $label Badge or "installing" label element. * @param {object} $button Action button element. */ clearInstalling: function( $label, $button ) { $label.removeClass( 'wp-mail-smtp-wpcode-installing-in-progress' ).text( '' ); $button.removeClass( 'wp-mail-smtp-btn-loading' ); }, /** * Filter the snippet grid against the search field value. * * @since 4.9.0 * * @param {object} searchField The search field HTML element. */ searchSnippet: function( searchField ) { var searchTerm = $( searchField ).val(); var searchResults = app.snippetSearch.search( searchTerm ); var $noResults = $( '#wp-mail-smtp-wpcode-no-results' ); if ( searchResults.length === 0 ) { $noResults.show(); } else { $noResults.hide(); } }, /** * Active-state "Install Snippet": show an installing state, then let the * link navigate to WPCode's install screen (perceived-load only, no AJAX). * * @since 4.9.0 */ installSnippet: function() { var $button = $( this ); // Edit is a plain navigation to the WPCode edit screen; no JS needed. if ( $button.data( 'action' ) === 'edit' ) { return; } app.setInstalling( $button.closest( '.wp-mail-smtp-wpcode-snippet' ).find( '.wp-mail-smtp-wpcode-snippet-badge' ), $button ); }, /** * Card "Install Snippet" when WPCode is installed but inactive: activate * WPCode, then navigate to the snippet's install URL. On activation * failure, show the activation popup. * * @since 4.9.0 * * @param {object} event The click event. */ onActivatePluginClick: function( event ) { event.preventDefault(); var $button = $( this ); var $badge = $button.closest( '.wp-mail-smtp-wpcode-snippet' ).find( '.wp-mail-smtp-wpcode-snippet-badge' ); app.setInstalling( $badge, $button ); app.activatePluginThenInstallSnippet( $button.data( 'library-id' ), $button.data( 'plugin' ), function() { app.clearInstalling( $badge, $button ); app.showManualActivationPluginPopup(); } ); }, /** * Activate WPCode via AJAX, then resolve the snippet's install URL via a * second AJAX request and navigate there. If activation fails, run the * provided callback; if only the URL lookup fails, reload so the tab * re-renders in its active state. * * @since 4.9.0 * * @param {number} libraryId The snippet library id. * @param {string} plugin WPCode plugin path. * @param {Function} onActivateFail Called when activation fails. */ activatePluginThenInstallSnippet: function( libraryId, plugin, onActivateFail ) { app.post( 'wp_mail_smtp_ajax', { task: 'about_plugin_activate', plugin: plugin } ) .done( function( response ) { if ( ! response || ! response.success ) { onActivateFail(); return; } app.navigateToSnippetInstall( libraryId ); } ) .fail( function() { onActivateFail(); } ); }, /** * Resolve a snippet's WPCode install URL (now that WPCode is active) via * AJAX and navigate to it. Falls back to a reload if the URL can't be * resolved, so the tab still re-renders in its active state. * * @since 4.9.0 * * @param {number} libraryId The snippet library id. */ navigateToSnippetInstall: function( libraryId ) { var extra = {}; extra['library_id'] = libraryId; // eslint-disable-line dot-notation app.post( 'wp_mail_smtp_get_wpcode_snippet_install_url', extra ) .done( function( response ) { if ( response && response.success && response.data && response.data.install_url ) { window.location.href = response.data.install_url; return; } window.location.reload(); } ) .fail( function() { window.location.reload(); } ); }, /** * Install and activate WPCode via AJAX. Runs onDone on full success, or * onError('install') if the install failed / errored, or onError('activate') * if WPCode installed but silent activation failed. * * WP returns logical failures with HTTP 200 + success:false, so a failed * install lands in .done (not .fail) and must be checked explicitly. * * @since 4.9.0 * * @param {string} plugin WPCode download URL. * @param {Function} onDone Called after a successful install + activation. * @param {Function} onError Called with 'install' or 'activate' on failure. */ installAndActivatePlugin: function( plugin, onDone, onError ) { app.post( 'wp_mail_smtp_ajax', { task: 'about_plugin_install', plugin: plugin } ) .done( function( response ) { if ( ! response || ! response.success ) { onError( 'install' ); return; } if ( response.data && response.data.is_activated === false ) { onError( 'activate' ); return; } onDone(); } ) .fail( function() { onError( 'install' ); } ); }, /** * Show the activate-WPCode popup. Its button forwards to the Plugins page * activation action for the installed WPCode plugin. * * @since 4.9.0 */ showManualActivationPluginPopup: function() { var l10n = window.wp_mail_smtp_code_snippets; $.confirm( { title: l10n.activate_popup_title, container: '#wp-mail-smtp', boxWidth: '600px', useBootstrap: false, closeIcon: true, draggable: false, content: '
' + l10n.activate_popup_desc + '
', buttons: { activate: { text: l10n.activate_popup_btn, btnClass: 'btn btn-confirm', action: function( button ) { button.addClass( 'wp-mail-smtp-btn-loading' ); window.location.href = l10n.activate_url; // Keep the popup open so the loader stays visible during navigation. return false; }, }, }, } ); }, /** * Map a snippet code_type to a CodeMirror mode. * * @since 4.9.0 * * @param {string} codeType Snippet code type. * * @returns {string} CodeMirror mode. */ mapMode: function( codeType ) { switch ( codeType ) { case 'js': case 'javascript': return 'javascript'; case 'css': return 'css'; case 'html': return 'htmlmixed'; default: return 'text/x-php'; } }, /** * Open the read-only code-preview modal for a snippet. * * @since 4.9.0 * * @param {object} event The click event. */ openViewSnippetModal: function( event ) { event.preventDefault(); var $btn = $( this ); var libraryId = $btn.data( 'library-id' ); var installUrl = $btn.data( 'install-url' ); var plugin = $btn.data( 'plugin' ); var l10n = window.wp_mail_smtp_code_snippets; // $.dialog has no jconfirm button row (whose styles can't be overridden // cleanly) — the action button is rendered inside our own content. $.dialog( { title: l10n.loading_text, container: '#wp-mail-smtp', boxWidth: '720px', useBootstrap: false, closeIcon: true, draggable: false, content: '