first
This commit is contained in:
BIN
wp-content/plugins/wp-smushit/_src/icon-warning.png
Normal file
BIN
wp-content/plugins/wp-smushit/_src/icon-warning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 558 B |
62
wp-content/plugins/wp-smushit/_src/js/app.js
Normal file
62
wp-content/plugins/wp-smushit/_src/js/app.js
Normal file
@ -0,0 +1,62 @@
|
||||
import '../scss/app.scss';
|
||||
|
||||
/**
|
||||
* Admin modules
|
||||
*/
|
||||
|
||||
const WP_Smush = WP_Smush || {};
|
||||
window.WP_Smush = WP_Smush;
|
||||
|
||||
/**
|
||||
* IE polyfill for includes.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @param {string} search
|
||||
* @param {number} start
|
||||
* @return {boolean} Returns true if searchString appears as a substring of the result of converting this
|
||||
* object to a String, at one or more positions that are
|
||||
* greater than or equal to position; otherwise, returns false.
|
||||
*/
|
||||
if ( ! String.prototype.includes ) {
|
||||
String.prototype.includes = function( search, start ) {
|
||||
if ( typeof start !== 'number' ) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if ( start + search.length > this.length ) {
|
||||
return false;
|
||||
}
|
||||
return this.indexOf( search, start ) !== -1;
|
||||
};
|
||||
}
|
||||
|
||||
require( './modules/helpers' );
|
||||
require( './modules/admin' );
|
||||
require( './modules/admin-common' );
|
||||
require( './modules/bulk-smush' );
|
||||
require( './modules/nextgen-bulk' );
|
||||
require( './modules/background-process' );
|
||||
require( './common/media-library-scanner' );
|
||||
require( './modules/media-library-scanner-on-bulk-smush' );
|
||||
require( './modules/media-library-scanner-on-dashboard' );
|
||||
require( './modules/onboarding' );
|
||||
require( './modules/directory-smush' );
|
||||
require( './smush/cdn' );
|
||||
require( './smush/webp' );
|
||||
require( './smush/lazy-load' );
|
||||
require( './modules/bulk-restore' );
|
||||
require( './smush/settings' );
|
||||
require( './smush/product-analytics' );
|
||||
|
||||
/**
|
||||
* Notice scripts.
|
||||
*
|
||||
* Notices are used in the following functions:
|
||||
*
|
||||
* @used-by \Smush\Core\Modules\Smush::smush_updated()
|
||||
* @used-by \Smush\Core\Integrations\S3::3_support_required_notice()
|
||||
* @used-by \Smush\App\Abstract_Page::installation_notice()
|
||||
*
|
||||
* TODO: should this be moved out in a separate file like common.scss?
|
||||
*/
|
||||
require( './modules/notice' );
|
222
wp-content/plugins/wp-smushit/_src/js/common/globalStats.js
Normal file
222
wp-content/plugins/wp-smushit/_src/js/common/globalStats.js
Normal file
@ -0,0 +1,222 @@
|
||||
/* global WP_Smush */
|
||||
export const UpsellManger = ( () => {
|
||||
return {
|
||||
maybeShowCDNActivationNotice() {
|
||||
if ( ! wp_smush_msgs.smush_cdn_activation_notice ) {
|
||||
return;
|
||||
}
|
||||
WP_Smush.helpers.renderActivationCDNNotice( wp_smush_msgs.smush_cdn_activation_notice );
|
||||
},
|
||||
maybeShowCDNUpsellForPreSiteOnStart() {
|
||||
const upsellCdn = document.querySelector( '.wp-smush-upsell-cdn' );
|
||||
if ( upsellCdn ) {
|
||||
upsellCdn.querySelector( 'p' ).innerHTML = wp_smush_msgs.processing_cdn_for_free;
|
||||
upsellCdn.classList.remove( 'sui-hidden' );
|
||||
}
|
||||
},
|
||||
maybeShowCDNUpsellForPreSiteOnCompleted() {
|
||||
const upsellCdn = document.querySelector( '.wp-smush-upsell-cdn' );
|
||||
if ( upsellCdn ) {
|
||||
upsellCdn.querySelector( 'p' ).innerHTML = wp_smush_msgs.processed_cdn_for_free;
|
||||
upsellCdn.classList.remove( 'sui-hidden' );
|
||||
}
|
||||
}
|
||||
};
|
||||
} )();
|
||||
export const GlobalStats = ( () => {
|
||||
const $ = document.querySelector.bind( document );
|
||||
const summarySmush = $( '.sui-summary-smush-metabox' );
|
||||
if ( ! summarySmush ) {
|
||||
return {};
|
||||
}
|
||||
// Cache initial stats.
|
||||
let boStats = window.wp_smushit_data.bo_stats;
|
||||
let globalStats = {
|
||||
count_images: 0,
|
||||
count_total: 0,
|
||||
count_resize: 0,
|
||||
count_skipped: 0,
|
||||
count_smushed: 0,
|
||||
savings_bytes: 0,
|
||||
savings_resize: 0,
|
||||
size_after: 0,
|
||||
size_before: 0,
|
||||
savings_percent: 0,
|
||||
percent_grade: 'sui-grade-dismissed',
|
||||
percent_metric: 0,
|
||||
percent_optimized: 0,
|
||||
remaining_count: 0,
|
||||
human_bytes: '',
|
||||
savings_conversion_human: '',
|
||||
savings_conversion: 0,
|
||||
};
|
||||
|
||||
const imageScore = $( '#smush-image-score' );
|
||||
const logBulk = $( '.smush-final-log .smush-bulk-errors' );
|
||||
const bulkSmushCountContent = $( '#wp-smush-bulk-content' );
|
||||
let allErrors = {};
|
||||
|
||||
const generateGlobalStatsFromSmushData = ( smushScriptData ) => {
|
||||
window.wp_smushit_data = Object.assign( window.wp_smushit_data, smushScriptData || {} );
|
||||
globalStats = Object.keys( globalStats ).reduce( function( newStats, key ) {
|
||||
if ( key in window.wp_smushit_data ) {
|
||||
newStats[ key ] = window.wp_smushit_data[ key ];
|
||||
}
|
||||
return newStats;
|
||||
}, {} );
|
||||
}
|
||||
|
||||
generateGlobalStatsFromSmushData( window.wp_smushit_data );
|
||||
|
||||
return {
|
||||
isChangedStats( newBoStats ) {
|
||||
const primaryKeys = [ 'total_items', 'processed_items', 'failed_items', 'is_cancelled', 'is_completed' ];
|
||||
return primaryKeys.some( ( key ) => {
|
||||
return newBoStats[ key ] !== boStats[ key ];
|
||||
} );
|
||||
},
|
||||
setBoStats( newBoStats ) {
|
||||
boStats = Object.assign( boStats, newBoStats || {} );
|
||||
return this;
|
||||
},
|
||||
getBoStats() {
|
||||
return boStats;
|
||||
},
|
||||
setGlobalStats( newGlobalStats ) {
|
||||
globalStats = Object.assign( globalStats, newGlobalStats || {} );
|
||||
return this;
|
||||
},
|
||||
getGlobalStats() {
|
||||
return globalStats;
|
||||
},
|
||||
/**
|
||||
* Circle progress bar.
|
||||
*/
|
||||
renderScoreProgress() {
|
||||
imageScore.className = imageScore.className.replace( /(^|\s)sui-grade-\S+/g, '' );
|
||||
imageScore.classList.add( globalStats.percent_grade );
|
||||
imageScore.dataset.score = globalStats.percent_optimized;
|
||||
imageScore.querySelector( '.sui-circle-score-label' ).innerHTML = globalStats.percent_optimized;
|
||||
|
||||
imageScore
|
||||
.querySelector( 'circle:last-child' )
|
||||
.setAttribute( 'style', '--metric-array:' + ( 2.63893782902 * globalStats.percent_metric ) + ' ' + ( 263.893782902 - globalStats.percent_metric ) );
|
||||
},
|
||||
/**
|
||||
* Summary detail - center meta box.
|
||||
*/
|
||||
renderSummaryDetail() {
|
||||
this.renderTotalStats();
|
||||
this.renderResizedStats();
|
||||
this.renderConversionSavings();
|
||||
},
|
||||
renderTotalStats() {
|
||||
// Total savings.
|
||||
summarySmush.querySelector( '.sui-summary-large.wp-smush-stats-human' ).innerHTML = globalStats.human_bytes;
|
||||
// Update the savings percent.
|
||||
summarySmush.querySelector( '.wp-smush-savings .wp-smush-stats-percent' ).innerHTML = globalStats.savings_percent;
|
||||
// To total smushed images files.
|
||||
summarySmush.querySelector( '.wp-smush-count-total .wp-smush-total-optimised' ).innerHTML = globalStats.count_images;
|
||||
},
|
||||
renderResizedStats() {
|
||||
const resizeCountElement = summarySmush.querySelector( '.wp-smush-count-resize-total' );
|
||||
if ( ! resizeCountElement ) {
|
||||
return;
|
||||
}
|
||||
if ( globalStats.count_resize > 0 ) {
|
||||
resizeCountElement.classList.remove( 'sui-hidden' );
|
||||
} else {
|
||||
resizeCountElement.classList.add( 'sui-hidden' );
|
||||
}
|
||||
resizeCountElement.querySelector( '.wp-smush-total-optimised' ).innerHTML = globalStats.count_resize;
|
||||
},
|
||||
renderConversionSavings() {
|
||||
// PNG2JPG Savings.
|
||||
const conversionSavingsElement = summarySmush.querySelector( '.smush-conversion-savings .wp-smush-stats' );
|
||||
if ( ! conversionSavingsElement ) {
|
||||
return;
|
||||
}
|
||||
conversionSavingsElement.innerHTML = globalStats.savings_conversion_human;
|
||||
if ( globalStats.savings_conversion > 0 ) {
|
||||
conversionSavingsElement.parentElement.classList.remove( 'sui-hidden' );
|
||||
} else {
|
||||
conversionSavingsElement.parentElement.classList.add( 'sui-hidden' );
|
||||
}
|
||||
},
|
||||
renderBoxSummary() {
|
||||
// Circle core progress.
|
||||
this.renderScoreProgress();
|
||||
// Summary detail.
|
||||
this.renderSummaryDetail();
|
||||
},
|
||||
setErrors( newErrors ) {
|
||||
allErrors = newErrors || {};
|
||||
},
|
||||
getErrors() {
|
||||
return allErrors;
|
||||
},
|
||||
renderErrors() {
|
||||
if ( ! Object.keys( allErrors ).length || ! boStats.is_completed ) {
|
||||
return;
|
||||
}
|
||||
const errors = [];
|
||||
const errorKeys = Object.keys( allErrors );
|
||||
// Cache error code to avoid double upsell notice.
|
||||
let showAnimatedUpsell = false;
|
||||
errorKeys.map( ( image_id, index ) => {
|
||||
const upsellErrorCode = allErrors[ image_id ].error_code;
|
||||
if ( index < 5 && 'animated' === upsellErrorCode ) {
|
||||
showAnimatedUpsell = true;
|
||||
}
|
||||
errors.push( WP_Smush.helpers.prepareBulkSmushErrorRow(
|
||||
allErrors[ image_id ].error_message,
|
||||
allErrors[ image_id ].file_name,
|
||||
allErrors[ image_id ].thumbnail,
|
||||
image_id,
|
||||
'media',
|
||||
allErrors[ image_id ].error_code,
|
||||
) );
|
||||
}
|
||||
);
|
||||
logBulk.innerHTML = errors.join( '' );
|
||||
logBulk.parentElement.classList.remove( 'sui-hidden' );
|
||||
logBulk.parentElement.style.display = null;
|
||||
// Show view all.
|
||||
if ( errorKeys.length > 1 ) {
|
||||
$( '.smush-bulk-errors-actions' ).classList.remove( 'sui-hidden' );
|
||||
}
|
||||
|
||||
// Show animated upsell CDN if user disabled CDN and found an animated error in first 5 errors.
|
||||
if ( showAnimatedUpsell ) {
|
||||
UpsellManger.maybeShowCDNActivationNotice();
|
||||
}
|
||||
},
|
||||
resetAndHideBulkErrors() {
|
||||
if ( ! logBulk ) {
|
||||
return;
|
||||
}
|
||||
this.resetErrors();
|
||||
logBulk.parentElement.classList.add( 'sui-hidden' );
|
||||
logBulk.innerHTML = '';
|
||||
},
|
||||
resetErrors() {
|
||||
allErrors = {};
|
||||
},
|
||||
renderStats() {
|
||||
// Render Smush box summary.
|
||||
this.renderBoxSummary();
|
||||
// Render Errors.
|
||||
this.renderErrors();
|
||||
},
|
||||
maybeUpdateBulkSmushCountContent( newContent ) {
|
||||
if ( newContent && bulkSmushCountContent ) {
|
||||
bulkSmushCountContent.innerHTML = newContent;
|
||||
}
|
||||
},
|
||||
updateGlobalStatsFromSmushScriptData( smushScriptData ) {
|
||||
this.maybeUpdateBulkSmushCountContent( smushScriptData?.content );
|
||||
generateGlobalStatsFromSmushData( smushScriptData );
|
||||
return this;
|
||||
},
|
||||
};
|
||||
} )();
|
@ -0,0 +1,267 @@
|
||||
/* global WP_Smush */
|
||||
|
||||
/**
|
||||
* Abstract Media Library Scanner.
|
||||
*
|
||||
*/
|
||||
import Fetcher from '../utils/fetcher';
|
||||
import { scanProgressBar } from './progressbar';
|
||||
import { GlobalStats } from './globalStats';
|
||||
const { __ } = wp.i18n;
|
||||
export default class MediaLibraryScanner {
|
||||
constructor() {
|
||||
this.autoSyncDuration = 1500;
|
||||
this.progressTimeoutId = 0;
|
||||
this.scanProgress = scanProgressBar( this.autoSyncDuration );
|
||||
}
|
||||
|
||||
startScan( optimizeOnScanCompleted = false ) {
|
||||
this.onStart();
|
||||
return Fetcher.scanMediaLibrary.start( optimizeOnScanCompleted ).then( ( response ) => {
|
||||
if ( ! response?.success ) {
|
||||
this.onStartFailure( response );
|
||||
return;
|
||||
}
|
||||
this.showProgressBar().autoSyncStatus();
|
||||
} );
|
||||
}
|
||||
|
||||
onStart() {
|
||||
// Do nothing at the moment.
|
||||
}
|
||||
|
||||
onStartFailure( response ) {
|
||||
WP_Smush.helpers.showNotice( response, {
|
||||
showdismiss: true,
|
||||
autoclose: false,
|
||||
} );
|
||||
}
|
||||
|
||||
showProgressBar() {
|
||||
this.onShowProgressBar();
|
||||
this.scanProgress.reset().setOnCancelCallback( this.showStopScanningModal.bind( this ) ).open();
|
||||
return this;
|
||||
}
|
||||
|
||||
onShowProgressBar() {
|
||||
// Do nothing at the moment.
|
||||
}
|
||||
|
||||
showStopScanningModal() {
|
||||
if ( ! window.SUI ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onShowStopScanningModal();
|
||||
|
||||
window.SUI.openModal(
|
||||
'smush-stop-scanning-dialog',
|
||||
'wpbody-content',
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
onShowStopScanningModal() {
|
||||
this.registerCancelProcessEvent();
|
||||
}
|
||||
|
||||
registerCancelProcessEvent() {
|
||||
const stopScanButton = document.querySelector( '.smush-stop-scanning-dialog-button' );
|
||||
if ( ! stopScanButton ) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopScanButton.addEventListener( 'click', this.cancelProgress.bind( this ) );
|
||||
}
|
||||
|
||||
closeStopScanningModal() {
|
||||
if ( ! window.SUI ) {
|
||||
return;
|
||||
}
|
||||
const stopScanningElement = document.querySelector( '#smush-stop-scanning-dialog' );
|
||||
const isModalClosed = ( ! stopScanningElement ) || ! stopScanningElement.classList.contains( 'sui-content-fade-in' );
|
||||
if ( isModalClosed ) {
|
||||
return;
|
||||
}
|
||||
window.SUI.closeModal( 'smush-stop-scanning-dialog' );
|
||||
}
|
||||
|
||||
closeProgressBar() {
|
||||
this.onCloseProgressBar();
|
||||
this.scanProgress.close();
|
||||
}
|
||||
|
||||
onCloseProgressBar() {
|
||||
// Do nothing at the moment.
|
||||
}
|
||||
|
||||
updateProgress( stats ) {
|
||||
const totalItems = this.getTotalItems( stats );
|
||||
const processedItems = this.getProcessedItems( stats );
|
||||
|
||||
return this.scanProgress.update( processedItems, totalItems );
|
||||
}
|
||||
|
||||
getProcessedItems( stats ) {
|
||||
return stats?.processed_items || 0;
|
||||
}
|
||||
|
||||
getTotalItems( stats ) {
|
||||
return stats?.total_items || 0;
|
||||
}
|
||||
|
||||
cancelProgress() {
|
||||
this.scanProgress.setCancelButtonOnCancelling();
|
||||
return Fetcher.scanMediaLibrary.cancel().then( ( response ) => {
|
||||
if ( ! response?.success ) {
|
||||
this.onCancelFailure( response );
|
||||
return;
|
||||
}
|
||||
this.onCancelled( response.data );
|
||||
} );
|
||||
}
|
||||
|
||||
onCancelFailure( response ) {
|
||||
WP_Smush.helpers.showNotice( response, {
|
||||
showdismiss: true,
|
||||
autoclose: false,
|
||||
} );
|
||||
this.scanProgress.resetCancelButtonOnFailure();
|
||||
}
|
||||
|
||||
getErrorProgressMessage() {
|
||||
return __( 'Unfortunately the scan hit an error due to limited resources on your site, we have adjusted the scan to use fewer resources the next time.', 'wp-smushit' );
|
||||
}
|
||||
|
||||
onDead( stats ) {
|
||||
this.clearProgressTimeout();
|
||||
this.closeProgressBar();
|
||||
this.closeStopScanningModal();
|
||||
this.showRetryScanModal();
|
||||
}
|
||||
|
||||
showRetryScanModal() {
|
||||
const retryScanModalElement = document.getElementById( 'smush-retry-scan-notice' );
|
||||
if ( ! window.SUI || ! retryScanModalElement ) {
|
||||
return;
|
||||
}
|
||||
|
||||
retryScanModalElement.querySelector('.smush-retry-scan-notice-button').onclick = (e) => {
|
||||
window.SUI.closeModal( 'smush-retry-scan-notice' );
|
||||
const recheckImagesBtn = document.querySelector( '.wp-smush-scan' );
|
||||
if ( ! recheckImagesBtn ) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
recheckImagesBtn.click();
|
||||
}
|
||||
|
||||
window.SUI.openModal(
|
||||
'smush-retry-scan-notice',
|
||||
'wpbody-content',
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
onCompleted( stats ) {
|
||||
this.onFinish( stats );
|
||||
}
|
||||
|
||||
onCancelled( stats ) {
|
||||
this.onFinish( stats );
|
||||
}
|
||||
|
||||
onFinish( stats ) {
|
||||
this.clearProgressTimeout();
|
||||
const globalStats = stats?.global_stats;
|
||||
this.updateGlobalStatsAndBulkContent( globalStats );
|
||||
this.closeProgressBar();
|
||||
this.closeStopScanningModal();
|
||||
}
|
||||
|
||||
clearProgressTimeout() {
|
||||
if ( this.progressTimeoutId ) {
|
||||
clearTimeout( this.progressTimeoutId );
|
||||
}
|
||||
}
|
||||
|
||||
updateGlobalStatsAndBulkContent( globalStats ) {
|
||||
if ( ! globalStats ) {
|
||||
return;
|
||||
}
|
||||
GlobalStats.updateGlobalStatsFromSmushScriptData( globalStats );
|
||||
GlobalStats.renderStats();
|
||||
}
|
||||
|
||||
getStatus() {
|
||||
return Fetcher.scanMediaLibrary.getScanStatus();
|
||||
}
|
||||
|
||||
autoSyncStatus() {
|
||||
const startTime = new Date().getTime();
|
||||
this.getStatus().then( ( response ) => {
|
||||
if ( ! response?.success ) {
|
||||
return;
|
||||
}
|
||||
const stats = response.data;
|
||||
|
||||
if ( stats.is_dead ) {
|
||||
this.onDead( response.data );
|
||||
return;
|
||||
}
|
||||
|
||||
this.beforeUpdateStatus( stats );
|
||||
|
||||
this.updateProgress( stats ).then( () => {
|
||||
this.scanProgress.increaseDurationToHaveChangeOnProgress( new Date().getTime() - startTime );
|
||||
|
||||
const isCompleted = stats?.is_completed;
|
||||
if ( isCompleted ) {
|
||||
this.onCompleted( stats );
|
||||
return;
|
||||
}
|
||||
const isCancelled = stats?.is_cancelled;
|
||||
if ( isCancelled ) {
|
||||
this.onCancelled( stats );
|
||||
return;
|
||||
}
|
||||
|
||||
this.progressTimeoutId = setTimeout( () => this.autoSyncStatus(), this.autoSyncDuration );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
beforeUpdateStatus() {
|
||||
// Do nothing at the moment.
|
||||
}
|
||||
|
||||
setInnerText( element, newText ) {
|
||||
if ( ! element ) {
|
||||
return;
|
||||
}
|
||||
element.dataset.originalText = element.dataset.originalText || element.innerText.trim();
|
||||
element.innerText = newText;
|
||||
}
|
||||
|
||||
revertInnerText( element ) {
|
||||
if ( ! element || ! element.dataset.originalText ) {
|
||||
return;
|
||||
}
|
||||
element.innerText = element.dataset.originalText.trim();
|
||||
}
|
||||
|
||||
hideAnElement( element ) {
|
||||
if ( element ) {
|
||||
element.classList.add( 'sui-hidden' );
|
||||
}
|
||||
}
|
||||
|
||||
showAnElement( element ) {
|
||||
if ( element ) {
|
||||
element.classList.remove( 'sui-hidden' );
|
||||
}
|
||||
}
|
||||
}
|
302
wp-content/plugins/wp-smushit/_src/js/common/progressbar.js
Normal file
302
wp-content/plugins/wp-smushit/_src/js/common/progressbar.js
Normal file
@ -0,0 +1,302 @@
|
||||
/* global WP_Smush */
|
||||
|
||||
/**
|
||||
* SmushProgressBar
|
||||
* TODO: Update progressbar for free version.
|
||||
*
|
||||
* @param autoSyncDuration
|
||||
*/
|
||||
export const scanProgressBar = ( autoSyncDuration ) => {
|
||||
const { __, _n } = wp.i18n;
|
||||
const scanProgressBar = document.querySelector( '.wp-smush-scan-progress-bar-wrapper' );
|
||||
const percentElement = scanProgressBar.querySelector( '.wp-smush-progress-percent' );
|
||||
const progressElement = scanProgressBar.querySelector( '.wp-smush-progress-inner' );
|
||||
const remainingTimeElement = scanProgressBar.querySelector( '.wp-smush-remaining-time' );
|
||||
const cancelBtn = scanProgressBar.querySelector( '.wp-smush-cancel-scan-progress-btn' );
|
||||
const holdOnNoticeElement = scanProgressBar.querySelector( '.wp-smush-scan-hold-on-notice' );
|
||||
let onCancelCallback = () => {};
|
||||
let intervalProgressAnimation = 0;
|
||||
// It should be smaller than autoSyncDuration.
|
||||
const progressTransitionDuration = autoSyncDuration - 300;//1200
|
||||
scanProgressBar.style.setProperty( '--progress-transition-duration', progressTransitionDuration / 1000 + 's' );
|
||||
|
||||
let prevProcessedItems = window.wp_smushit_data?.media_library_scan?.processed_items || 0;
|
||||
const cacheProcessTimePerItem = [];
|
||||
let durationToHaveChangeOnProgress = autoSyncDuration;
|
||||
let timeLimitToShowNotice = autoSyncDuration * 10;// 15s.
|
||||
return {
|
||||
update( processedItems, totalItems ) {
|
||||
this.updateRemainingTime( processedItems, totalItems );
|
||||
|
||||
let width = ( totalItems && Math.floor( processedItems / totalItems * 100 ) ) || 0;
|
||||
width = Math.min( width, 100 );
|
||||
|
||||
let currentWidth = progressElement.style.width;
|
||||
currentWidth = ( currentWidth && currentWidth.replace( '%', '' ) ) || 0;
|
||||
progressElement.style.width = width + '%';
|
||||
|
||||
return this.animateProgressBar( currentWidth, width );
|
||||
},
|
||||
animateProgressBar( currentWidth, width ) {
|
||||
if ( intervalProgressAnimation ) {
|
||||
clearInterval( intervalProgressAnimation );
|
||||
}
|
||||
return new Promise( ( resolve ) => {
|
||||
const delayTime = progressTransitionDuration / ( width - currentWidth );
|
||||
intervalProgressAnimation = setInterval( () => {
|
||||
// Progress bar label.
|
||||
percentElement.innerHTML = currentWidth + '%';
|
||||
currentWidth++;
|
||||
if ( currentWidth > width ) {
|
||||
resolve();
|
||||
clearInterval( intervalProgressAnimation );
|
||||
}
|
||||
}, delayTime );
|
||||
} );
|
||||
},
|
||||
updateRemainingTime( processedItems, totalItems ) {
|
||||
if ( ! remainingTimeElement ) {
|
||||
return;
|
||||
}
|
||||
const processTimePerItem = this.calcProcessTimePerItem( processedItems ) || 500;
|
||||
const remainingTime = processTimePerItem * ( totalItems - processedItems );
|
||||
remainingTimeElement.innerText = this.formatTime( remainingTime );
|
||||
},
|
||||
calcProcessTimePerItem( processedItems ) {
|
||||
if ( ! processedItems ) {
|
||||
return;
|
||||
}
|
||||
prevProcessedItems = prevProcessedItems <= processedItems ? prevProcessedItems : 0;
|
||||
if ( prevProcessedItems != processedItems ) {
|
||||
const processTimePerItem = Math.floor( durationToHaveChangeOnProgress / ( processedItems - prevProcessedItems ) );
|
||||
|
||||
prevProcessedItems = processedItems;
|
||||
cacheProcessTimePerItem.push( processTimePerItem );
|
||||
this.resetDurationToHaveChangeOnProgress();
|
||||
} else {
|
||||
this.increaseDurationToHaveChangeOnProgress( autoSyncDuration );
|
||||
}
|
||||
|
||||
if ( ! cacheProcessTimePerItem.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
return cacheProcessTimePerItem.reduce(
|
||||
( accumulator, processTime ) => accumulator + processTime, 0
|
||||
) / cacheProcessTimePerItem.length;
|
||||
},
|
||||
increaseDurationToHaveChangeOnProgress( increaseTime ) {
|
||||
durationToHaveChangeOnProgress += increaseTime;
|
||||
if ( durationToHaveChangeOnProgress > timeLimitToShowNotice ) {
|
||||
this.showHoldOnNotice();
|
||||
}
|
||||
},
|
||||
showHoldOnNotice() {
|
||||
holdOnNoticeElement.classList.remove( 'sui-hidden' );
|
||||
timeLimitToShowNotice = 100000000;
|
||||
},
|
||||
resetHoldOnNoticeVisibility() {
|
||||
holdOnNoticeElement.classList.add( 'sui-hidden' );
|
||||
},
|
||||
resetDurationToHaveChangeOnProgress() {
|
||||
durationToHaveChangeOnProgress = autoSyncDuration;
|
||||
},
|
||||
formatTime( totalMilliSeconds ) {
|
||||
const totalSeconds = Math.floor( ( totalMilliSeconds + progressTransitionDuration ) / 1000 );
|
||||
const seconds = totalSeconds % 60;
|
||||
const minutes = Math.floor( totalSeconds / 60 );
|
||||
|
||||
let timeString = '';
|
||||
if ( minutes ) {
|
||||
timeString += minutes + ' ' + _n( 'minute', 'minutes', minutes, 'wp-smushit' );
|
||||
}
|
||||
|
||||
timeString += ' ' + seconds + ' ' + _n( 'second', 'seconds', seconds, 'wp-smushit' );
|
||||
|
||||
return timeString.trim();
|
||||
},
|
||||
reset() {
|
||||
progressElement.style.width = '0%';
|
||||
percentElement.innerHTML = '0%';
|
||||
|
||||
this.resetCancelButton();
|
||||
this.resetHoldOnNoticeVisibility();
|
||||
return this;
|
||||
},
|
||||
open() {
|
||||
cancelBtn.onclick = onCancelCallback;
|
||||
scanProgressBar.classList.remove( 'sui-hidden' );
|
||||
},
|
||||
close() {
|
||||
scanProgressBar.classList.add( 'sui-hidden' );
|
||||
this.reset();
|
||||
},
|
||||
setOnCancelCallback( callBack ) {
|
||||
if ( 'function' !== typeof callBack ) {
|
||||
return;
|
||||
}
|
||||
onCancelCallback = callBack;
|
||||
return this;
|
||||
},
|
||||
setCancelButtonLabel( textContent ) {
|
||||
cancelBtn.textContent = textContent;
|
||||
return this;
|
||||
},
|
||||
setCancelButtonOnCancelling() {
|
||||
this.setCancelButtonLabel( wp_smush_msgs.cancelling );
|
||||
this.setOnCancelCallback( () => false );
|
||||
cancelBtn.setAttribute( 'disabled', true );
|
||||
},
|
||||
resetCancelButton() {
|
||||
this.setOnCancelCallback( () => {} );
|
||||
this.resetCancelButtonLabel();
|
||||
cancelBtn.removeAttribute( 'disabled' );
|
||||
},
|
||||
resetCancelButtonLabel() {
|
||||
this.setCancelButtonLabel( __( 'Cancel Scan', 'wp-smushit' ) );
|
||||
},
|
||||
resetCancelButtonOnFailure() {
|
||||
this.resetCancelButtonLabel();
|
||||
cancelBtn.removeAttribute( 'disabled' );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const SmushProgressBar = () => {
|
||||
'use strict';
|
||||
const progressBar = document.querySelector( '.wp-smush-bulk-progress-bar-wrapper' );
|
||||
if ( ! progressBar ) {
|
||||
return {
|
||||
isEmptyObject: true,
|
||||
};
|
||||
}
|
||||
const cancelBtn = progressBar.querySelector( '.wp-smush-cancel-btn' );
|
||||
const bulkSmushDescription = document.querySelector( '.wp-smush-bulk-wrapper' );
|
||||
const bulkRunningNotice = progressBar.querySelector( '#wp-smush-running-notice' );
|
||||
const bulkSmushAllDone = document.querySelector( '.wp-smush-all-done' );
|
||||
let isStateHidden = false;
|
||||
let onCancelCallback = () => {};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Update progress bar.
|
||||
*
|
||||
* @param {number} processedItems
|
||||
* @param {number} totalItems
|
||||
*/
|
||||
update( processedItems, totalItems ) {
|
||||
let width = totalItems && Math.floor( processedItems / totalItems * 100 ) || 0;
|
||||
width = Math.min( width, 100 );
|
||||
|
||||
// Progress bar label.
|
||||
progressBar.querySelector( '.wp-smush-images-percent' ).innerHTML = width + '%';
|
||||
// Progress bar.
|
||||
progressBar.querySelector( '.wp-smush-progress-inner' ).style.width = width + '%';
|
||||
|
||||
// Update processed/total.
|
||||
const processStateStats = progressBar.querySelector( '.sui-progress-state-text' );
|
||||
processStateStats.firstElementChild.innerHTML = processedItems;
|
||||
processStateStats.lastElementChild.innerHTML = totalItems;
|
||||
|
||||
return this;
|
||||
},
|
||||
close() {
|
||||
progressBar.classList.add( 'sui-hidden' );
|
||||
this.setCancelButtonLabel( window.wp_smush_msgs.cancel )
|
||||
.setOnCancelCallback( () => {} )
|
||||
.update( 0, 0 );
|
||||
this.resetOriginalNotice();
|
||||
return this;
|
||||
},
|
||||
show() {
|
||||
// Show progress bar.
|
||||
cancelBtn.onclick = onCancelCallback;
|
||||
progressBar.classList.remove( 'sui-hidden' );
|
||||
this.hideBulkSmushDescription();
|
||||
this.hideBulkSmushAllDone();
|
||||
this.hideRecheckImagesNotice();
|
||||
},
|
||||
setCancelButtonLabel( textContent ) {
|
||||
cancelBtn.textContent = textContent;
|
||||
return this;
|
||||
},
|
||||
showBulkSmushDescription() {
|
||||
bulkSmushDescription.classList.remove( 'sui-hidden' );
|
||||
},
|
||||
hideBulkSmushDescription() {
|
||||
bulkSmushDescription.classList.add( 'sui-hidden' );
|
||||
},
|
||||
showBulkSmushAllDone() {
|
||||
bulkSmushAllDone.classList.remove( 'sui-hidden' );
|
||||
},
|
||||
hideBulkSmushAllDone() {
|
||||
bulkSmushAllDone.classList.add( 'sui-hidden' );
|
||||
},
|
||||
hideState() {
|
||||
if ( isStateHidden ) {
|
||||
return this;
|
||||
}
|
||||
isStateHidden = true;
|
||||
progressBar.querySelector( '.sui-progress-state' ).classList.add( 'sui-hidden' );
|
||||
return this;
|
||||
},
|
||||
showState() {
|
||||
if ( ! isStateHidden ) {
|
||||
return this;
|
||||
}
|
||||
isStateHidden = false;
|
||||
progressBar.querySelector( '.sui-progress-state' ).classList.remove( 'sui-hidden' );
|
||||
return this;
|
||||
},
|
||||
setNotice( inProcessNotice ) {
|
||||
const progressMessage = bulkRunningNotice.querySelector( '.sui-notice-message p' );
|
||||
this.cacheOriginalNotice( progressMessage );
|
||||
progressMessage.innerHTML = inProcessNotice;
|
||||
return this;
|
||||
},
|
||||
cacheOriginalNotice( progressMessage ) {
|
||||
if ( bulkRunningNotice.dataset.progressMessage ) {
|
||||
return;
|
||||
}
|
||||
bulkRunningNotice.dataset.progressMessage = progressMessage.innerHTML;
|
||||
},
|
||||
resetOriginalNotice() {
|
||||
if ( ! bulkRunningNotice.dataset.progressMessage ) {
|
||||
return;
|
||||
}
|
||||
const progressMessage = bulkRunningNotice.querySelector( '.sui-notice-message p' );
|
||||
progressMessage.innerHTML = bulkRunningNotice.dataset.progressMessage;
|
||||
},
|
||||
hideBulkProcessingNotice() {
|
||||
bulkRunningNotice.classList.add( 'sui-hidden' );
|
||||
return this;
|
||||
},
|
||||
showBulkProcessingNotice() {
|
||||
bulkRunningNotice.classList.remove( 'sui-hidden' );
|
||||
return this;
|
||||
},
|
||||
setCountUnitText( unitText ) {
|
||||
const progressUnit = progressBar.querySelector( '.sui-progress-state-unit' );
|
||||
progressUnit.innerHTML = unitText;
|
||||
},
|
||||
setOnCancelCallback( callBack ) {
|
||||
if ( 'function' !== typeof callBack ) {
|
||||
return;
|
||||
}
|
||||
onCancelCallback = callBack;
|
||||
return this;
|
||||
},
|
||||
disableExceedLimitMode() {
|
||||
progressBar.classList.remove( 'wp-smush-exceed-limit' );
|
||||
progressBar.querySelector( '#bulk-smush-resume-button' ).classList.add( 'sui-hidden' );
|
||||
},
|
||||
hideRecheckImagesNotice() {
|
||||
const recheckImagesNoticeElement = document.querySelector( '.wp-smush-recheck-images-notice-box' );
|
||||
if ( recheckImagesNoticeElement ) {
|
||||
recheckImagesNoticeElement.classList.add( 'sui-hidden' );
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
export default new SmushProgressBar();
|
@ -0,0 +1,11 @@
|
||||
import lazySizes from 'lazysizes';
|
||||
import 'lazysizes/plugins/native-loading/ls.native-loading';
|
||||
|
||||
lazySizes.cfg.nativeLoading = {
|
||||
setLoadingAttribute: true,
|
||||
disableListeners: {
|
||||
scroll: true,
|
||||
},
|
||||
};
|
||||
|
||||
lazySizes.init();
|
@ -0,0 +1,3 @@
|
||||
import lazySizes from 'lazysizes';
|
||||
|
||||
lazySizes.init();
|
@ -0,0 +1,362 @@
|
||||
import '../../scss/resize-detection.scss';
|
||||
|
||||
/**
|
||||
* Image resize detection (IRD).
|
||||
*
|
||||
* Show all wrongly scaled images with a highlighted border and resize box.
|
||||
*
|
||||
* Made in pure JS.
|
||||
* DO NOT ADD JQUERY SUPPORT!!!
|
||||
*
|
||||
* @since 2.9
|
||||
*/
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
const SmushIRS = {
|
||||
bar: document.getElementById( 'smush-image-bar' ),
|
||||
toggle: document.getElementById( 'smush-image-bar-toggle' ),
|
||||
images: {
|
||||
bigger: [],
|
||||
smaller: [],
|
||||
},
|
||||
strings: window.wp_smush_resize_vars,
|
||||
|
||||
/**
|
||||
* Init scripts.
|
||||
*/
|
||||
init() {
|
||||
/**
|
||||
* Make sure these are set, before we proceed.
|
||||
*/
|
||||
if ( ! this.bar ) {
|
||||
this.bar = document.getElementById( 'smush-image-bar' );
|
||||
}
|
||||
if ( ! this.toggle ) {
|
||||
this.toggle = document.getElementById(
|
||||
'smush-image-bar-toggle'
|
||||
);
|
||||
}
|
||||
|
||||
this.process();
|
||||
|
||||
// Register the event handler after everything is done.
|
||||
this.toggle.addEventListener(
|
||||
'click',
|
||||
this.handleToggleClick.bind( this )
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Do image processing.
|
||||
*/
|
||||
process() {
|
||||
const icon = this.toggle.querySelector( 'i' );
|
||||
|
||||
icon.classList.add( 'sui-icon-loader' );
|
||||
icon.classList.remove( 'sui-icon-info' );
|
||||
|
||||
this.detectImages();
|
||||
|
||||
if ( ! this.images.bigger.length && ! this.images.smaller.length ) {
|
||||
this.toggle.classList.add( 'smush-toggle-success' );
|
||||
document.getElementById(
|
||||
'smush-image-bar-notice'
|
||||
).style.display = 'block';
|
||||
document.getElementById(
|
||||
'smush-image-bar-notice-desc'
|
||||
).style.display = 'none';
|
||||
} else {
|
||||
this.toggle.classList.remove( 'smush-toggle-success' );
|
||||
document.getElementById(
|
||||
'smush-image-bar-notice'
|
||||
).style.display = 'none';
|
||||
document.getElementById(
|
||||
'smush-image-bar-notice-desc'
|
||||
).style.display = 'block';
|
||||
this.generateMarkup( 'bigger' );
|
||||
this.generateMarkup( 'smaller' );
|
||||
}
|
||||
|
||||
this.toggleDivs();
|
||||
|
||||
icon.classList.remove( 'sui-icon-loader' );
|
||||
icon.classList.add( 'sui-icon-info' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Various checks to see if the image should be processed.
|
||||
*
|
||||
* @param {Object} image
|
||||
* @return {boolean} Should skip image or not.
|
||||
*/
|
||||
shouldSkipImage( image ) {
|
||||
// Skip avatars.
|
||||
if ( image.classList.contains( 'avatar' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip images from Smush CDN with auto-resize feature.
|
||||
if (
|
||||
'string' === typeof image.getAttribute( 'no-resize-detection' )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip 1x1px images.
|
||||
if (
|
||||
image.clientWidth === image.clientHeight &&
|
||||
1 === image.clientWidth
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip 1x1px placeholders.
|
||||
if (
|
||||
image.naturalWidth === image.naturalHeight &&
|
||||
1 === image.naturalWidth
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If width attribute is not set, do not continue.
|
||||
return null === image.clientWidth || null === image.clientHeight;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get tooltip text.
|
||||
*
|
||||
* @param {Object} props
|
||||
* @return {string} Tooltip.
|
||||
*/
|
||||
getTooltipText( props ) {
|
||||
let tooltipText = '';
|
||||
|
||||
if ( props.bigger_width || props.bigger_height ) {
|
||||
/** @param {string} strings.large_image */
|
||||
tooltipText = this.strings.large_image;
|
||||
} else if ( props.smaller_width || props.smaller_height ) {
|
||||
/** @param {string} strings.small_image */
|
||||
tooltipText = this.strings.small_image;
|
||||
}
|
||||
|
||||
return tooltipText
|
||||
.replace( 'width', props.real_width )
|
||||
.replace( 'height', props.real_height );
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate markup.
|
||||
*
|
||||
* @param {string} type Accepts: 'bigger' or 'smaller'.
|
||||
*/
|
||||
generateMarkup( type ) {
|
||||
this.images[ type ].forEach( ( image, index ) => {
|
||||
const item = document.createElement( 'div' ),
|
||||
tooltip = this.getTooltipText( image.props );
|
||||
|
||||
item.setAttribute(
|
||||
'class',
|
||||
'smush-resize-box smush-tooltip smush-tooltip-constrained'
|
||||
);
|
||||
item.setAttribute( 'data-tooltip', tooltip );
|
||||
item.setAttribute( 'data-image', image.class );
|
||||
item.addEventListener( 'click', ( e ) =>
|
||||
this.highlightImage( e )
|
||||
);
|
||||
|
||||
item.innerHTML = `
|
||||
<div class="smush-image-info">
|
||||
<span>${ index + 1 }</span>
|
||||
<span class="smush-tag">${ image.props.computed_width } x ${ image.props.computed_height }px</span>
|
||||
<i class="smush-front-icons smush-front-icon-arrows-in" aria-hidden="true"> </i>
|
||||
<span class="smush-tag smush-tag-success">${ image.props.real_width } × ${ image.props.real_height }px</span>
|
||||
</div>
|
||||
<div class="smush-image-description">${ tooltip }</div>
|
||||
`;
|
||||
|
||||
document
|
||||
.getElementById( 'smush-image-bar-items-' + type )
|
||||
.appendChild( item );
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Show/hide sections based on images.
|
||||
*/
|
||||
toggleDivs() {
|
||||
const types = [ 'bigger', 'smaller' ];
|
||||
types.forEach( ( type ) => {
|
||||
const div = document.getElementById(
|
||||
'smush-image-bar-items-' + type
|
||||
);
|
||||
if ( 0 === this.images[ type ].length ) {
|
||||
div.style.display = 'none';
|
||||
} else {
|
||||
div.style.display = 'block';
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Scroll the selected image into view and highlight it.
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
highlightImage( e ) {
|
||||
this.removeSelection();
|
||||
|
||||
const el = document.getElementsByClassName(
|
||||
e.currentTarget.dataset.image
|
||||
);
|
||||
if ( 'undefined' !== typeof el[ 0 ] ) {
|
||||
// Display description box.
|
||||
e.currentTarget.classList.toggle( 'show-description' );
|
||||
|
||||
// Scroll and flash image.
|
||||
el[ 0 ].scrollIntoView( {
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'nearest',
|
||||
} );
|
||||
el[ 0 ].style.opacity = '0.5';
|
||||
setTimeout( () => {
|
||||
el[ 0 ].style.opacity = '1';
|
||||
}, 1000 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle click on the toggle item.
|
||||
*/
|
||||
handleToggleClick() {
|
||||
this.bar.classList.toggle( 'closed' );
|
||||
this.toggle.classList.toggle( 'closed' );
|
||||
this.removeSelection();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove selected items.
|
||||
*/
|
||||
removeSelection() {
|
||||
const items = document.getElementsByClassName( 'show-description' );
|
||||
if ( items.length > 0 ) {
|
||||
Array.from( items ).forEach( ( div ) =>
|
||||
div.classList.remove( 'show-description' )
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function to highlight all scaled images.
|
||||
*
|
||||
* Add yellow border and then show one small box to
|
||||
* resize the images as per the required size, on fly.
|
||||
*/
|
||||
detectImages() {
|
||||
const images = document.getElementsByTagName( 'img' );
|
||||
for ( const image of images ) {
|
||||
if ( this.shouldSkipImage( image ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get defined width and height.
|
||||
const props = {
|
||||
real_width: image.clientWidth,
|
||||
real_height: image.clientHeight,
|
||||
computed_width: image.naturalWidth,
|
||||
computed_height: image.naturalHeight,
|
||||
bigger_width: image.clientWidth * 1.5 < image.naturalWidth,
|
||||
bigger_height:
|
||||
image.clientHeight * 1.5 < image.naturalHeight,
|
||||
smaller_width: image.clientWidth > image.naturalWidth,
|
||||
smaller_height: image.clientHeight > image.naturalHeight,
|
||||
};
|
||||
|
||||
// In case image is in correct size, do not continue.
|
||||
if (
|
||||
! props.bigger_width &&
|
||||
! props.bigger_height &&
|
||||
! props.smaller_width &&
|
||||
! props.smaller_height
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const imgType =
|
||||
props.bigger_width || props.bigger_height
|
||||
? 'bigger'
|
||||
: 'smaller',
|
||||
imageClass =
|
||||
'smush-image-' + ( this.images[ imgType ].length + 1 );
|
||||
|
||||
// Fill the images arrays.
|
||||
this.images[ imgType ].push( {
|
||||
src: image,
|
||||
props,
|
||||
class: imageClass,
|
||||
} );
|
||||
|
||||
/**
|
||||
* Add class to original image.
|
||||
* Can't add two classes in single add(), because no support in IE11.
|
||||
* image.classList.add('smush-detected-img', imageClass);
|
||||
*/
|
||||
image.classList.add( 'smush-detected-img' );
|
||||
image.classList.add( imageClass );
|
||||
}
|
||||
}, // End detectImages()
|
||||
|
||||
/**
|
||||
* Allows refreshing the list. A good way is to refresh on lazyload actions.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*/
|
||||
refresh() {
|
||||
// Clear out classes on DOM.
|
||||
for ( let id in this.images.bigger ) {
|
||||
if ( this.images.bigger.hasOwnProperty( id ) ) {
|
||||
this.images.bigger[ id ].src.classList.remove(
|
||||
'smush-detected-img'
|
||||
);
|
||||
this.images.bigger[ id ].src.classList.remove(
|
||||
'smush-image-' + ++id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for ( let id in this.images.smaller ) {
|
||||
if ( this.images.smaller.hasOwnProperty( id ) ) {
|
||||
this.images.smaller[ id ].src.classList.remove(
|
||||
'smush-detected-img'
|
||||
);
|
||||
this.images.smaller[ id ].src.classList.remove(
|
||||
'smush-image-' + ++id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.images = {
|
||||
bigger: [],
|
||||
smaller: [],
|
||||
};
|
||||
|
||||
// This might be overkill - there will probably never be a situation when there are less images than on
|
||||
// initial page load.
|
||||
const elements = document.getElementsByClassName(
|
||||
'smush-resize-box'
|
||||
);
|
||||
while ( elements.length > 0 ) {
|
||||
elements[ 0 ].remove();
|
||||
}
|
||||
|
||||
this.process();
|
||||
},
|
||||
}; // End WP_Smush_IRS
|
||||
|
||||
/**
|
||||
* After page load, initialize toggle event.
|
||||
*/
|
||||
window.addEventListener( 'DOMContentLoaded', () => SmushIRS.init() );
|
||||
window.addEventListener( 'lazyloaded', () => SmushIRS.refresh() );
|
||||
}() );
|
83
wp-content/plugins/wp-smushit/_src/js/global.js
Normal file
83
wp-content/plugins/wp-smushit/_src/js/global.js
Normal file
@ -0,0 +1,83 @@
|
||||
import '../scss/common.scss';
|
||||
|
||||
/* global ajaxurl */
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const dismissNoticeButton = document.querySelectorAll(
|
||||
'.smush-dismissible-notice .smush-dismiss-notice-button'
|
||||
);
|
||||
dismissNoticeButton.forEach((button) => {
|
||||
button.addEventListener('click', handleDismissNotice);
|
||||
});
|
||||
|
||||
function handleDismissNotice(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const button = event.target;
|
||||
const notice = button.closest('.smush-dismissible-notice');
|
||||
const key = notice.getAttribute('data-key');
|
||||
|
||||
dismissNotice( key, notice );
|
||||
}
|
||||
|
||||
function dismissNotice( key, notice ) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(
|
||||
'POST',
|
||||
ajaxurl + '?action=smush_dismiss_notice&key=' + key + '&_ajax_nonce=' + smush_global.nonce,
|
||||
true
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if (notice) {
|
||||
notice.querySelector('button.notice-dismiss').dispatchEvent(new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
}));
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
|
||||
// Show header notices.
|
||||
const handleHeaderNotice = () => {
|
||||
const headerNotice = document.querySelector('.wp-smush-dismissible-header-notice');
|
||||
if ( ! headerNotice || ! headerNotice.id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { dismissKey, message } = headerNotice.dataset;
|
||||
if ( ! dismissKey || ! message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
headerNotice.onclick = (e) => {
|
||||
const classList = e.target.classList;
|
||||
const isDismissButton = classList && ( classList.contains('sui-icon-check') || classList.contains('sui-button-icon') );
|
||||
if ( ! isDismissButton ) {
|
||||
return;
|
||||
}
|
||||
dismissNotice( dismissKey );
|
||||
}
|
||||
|
||||
const noticeOptions = {
|
||||
type: 'warning',
|
||||
icon: 'info',
|
||||
dismiss: {
|
||||
show: true,
|
||||
label: wp_smush_msgs.noticeDismiss,
|
||||
tooltip: wp_smush_msgs.noticeDismissTooltip,
|
||||
},
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
headerNotice.id,
|
||||
message,
|
||||
noticeOptions
|
||||
);
|
||||
}
|
||||
|
||||
handleHeaderNotice();
|
||||
|
||||
});
|
75
wp-content/plugins/wp-smushit/_src/js/mixpanel.js
Normal file
75
wp-content/plugins/wp-smushit/_src/js/mixpanel.js
Normal file
@ -0,0 +1,75 @@
|
||||
/* global wp_smush_mixpanel */
|
||||
|
||||
import mixpanel from "mixpanel-browser";
|
||||
|
||||
class MixPanel {
|
||||
constructor() {
|
||||
// Opt out event is not triggered via js so only initial mixpanel when it's enabled.
|
||||
this.mixpanelInstance = this.allowToTrack() && mixpanel.init(wp_smush_mixpanel.token, {
|
||||
opt_out_tracking_by_default: ! this.allowToTrack(),
|
||||
loaded: (mixpanel) => {
|
||||
mixpanel.identify(wp_smush_mixpanel.unique_id);
|
||||
mixpanel.register(wp_smush_mixpanel.super_properties);
|
||||
|
||||
if (mixpanel.has_opted_in_tracking() !== this.allowToTrack()) {
|
||||
// The status cached by MixPanel in the local storage is different from the settings. Clear the cache.
|
||||
mixpanel.clear_opt_in_out_tracking();
|
||||
}
|
||||
}
|
||||
}, 'smush');
|
||||
}
|
||||
|
||||
allowToTrack() {
|
||||
return !! wp_smush_mixpanel.opt_in;
|
||||
}
|
||||
|
||||
track(event, properties = {}) {
|
||||
if ( wp_smush_mixpanel.debug ) {
|
||||
console.log( 'Event:', event, properties );
|
||||
}
|
||||
this.mixpanelInstance && this.mixpanelInstance.track(event, properties);
|
||||
}
|
||||
|
||||
trackBulkSmushCompleted( globalStats ) {
|
||||
const {
|
||||
savings_bytes,
|
||||
count_images,
|
||||
percent_optimized,
|
||||
savings_percent,
|
||||
count_resize,
|
||||
savings_resize
|
||||
} = globalStats;
|
||||
this.track('Bulk Smush Completed', {
|
||||
'Total Savings': this.convertToMegabytes( savings_bytes ),
|
||||
'Total Images': count_images,
|
||||
'Media Optimization Percentage': parseFloat( percent_optimized ),
|
||||
'Percentage of Savings': parseFloat( savings_percent ),
|
||||
'Images Resized': count_resize,
|
||||
'Resize Savings': this.convertToMegabytes( savings_resize )
|
||||
});
|
||||
}
|
||||
|
||||
trackBulkSmushCancel() {
|
||||
this.track('Bulk Smush Cancelled');
|
||||
}
|
||||
|
||||
convertToMegabytes( sizeInBytes ) {
|
||||
const unitMB = Math.pow( 1024, 2 );
|
||||
const sizeInMegabytes = sizeInBytes/unitMB;
|
||||
return sizeInMegabytes && parseFloat(sizeInMegabytes.toFixed(2)) || 0;
|
||||
}
|
||||
}
|
||||
|
||||
const mixPanelInstance = () => {
|
||||
let instance;
|
||||
return {
|
||||
getInstance: () => {
|
||||
if ( ! instance ) {
|
||||
instance = new MixPanel();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default mixPanelInstance();
|
@ -0,0 +1,20 @@
|
||||
jQuery(function ($) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Handle the Smush Stats link click
|
||||
*/
|
||||
$('body').on('click', 'a.smush-stats-details', function (e) {
|
||||
//If disabled
|
||||
if ($(this).prop('disabled')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// prevent the default action
|
||||
e.preventDefault();
|
||||
//Replace the `+` with a `-`
|
||||
const slide_symbol = $(this).find('.stats-toggle');
|
||||
$(this).parents().eq(1).find('.smush-stats-wrapper').slideToggle();
|
||||
slide_symbol.text(slide_symbol.text() == '+' ? '-' : '+');
|
||||
});
|
||||
});
|
1028
wp-content/plugins/wp-smushit/_src/js/modules/admin.js
Normal file
1028
wp-content/plugins/wp-smushit/_src/js/modules/admin.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,395 @@
|
||||
/* global WP_Smush */
|
||||
|
||||
/**
|
||||
* Bulk Smush Background Optimization.
|
||||
*
|
||||
* @since 3.12.0
|
||||
*/
|
||||
import Fetcher from '../utils/fetcher';
|
||||
import MixPanel from "../mixpanel";
|
||||
import SmushProgress from '../common/progressbar';
|
||||
import {GlobalStats, UpsellManger} from "../common/globalStats";
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
if (!window.wp_smush_msgs) {
|
||||
return;
|
||||
}
|
||||
const $ = document.querySelector.bind(document);
|
||||
const NO_FREE_LIMITED = 50;
|
||||
|
||||
/**
|
||||
* Handle Background Process.
|
||||
* @returns
|
||||
*/
|
||||
const BackgroundProcess = () => {
|
||||
return {
|
||||
handle(action) {
|
||||
return Fetcher.background[action]();
|
||||
},
|
||||
initState() {
|
||||
return Fetcher.background.initState();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Optimization.
|
||||
*/
|
||||
const BackgroundSmush = (() => {
|
||||
|
||||
const startBtn = window.wp_smushit_data && window.wp_smushit_data.bo_stats && $('.wp-smush-bo-start');
|
||||
if (!startBtn) {
|
||||
return;
|
||||
}
|
||||
|
||||
const mixPanel = MixPanel.getInstance();
|
||||
const BO = new BackgroundProcess();
|
||||
const bulkWrapper = $('.bulk-smush-wrapper');
|
||||
const reScanImagesButton = $('.wp-smush-scan');
|
||||
let intervalHandle = 0;
|
||||
let cancellationInProgress = false;
|
||||
return {
|
||||
hookStatusChecks() {
|
||||
if (intervalHandle) {
|
||||
// Already done
|
||||
return;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
let statusSyncInProgress = false;
|
||||
let statSyncInProgress = false;
|
||||
intervalHandle = setInterval(() => {
|
||||
if (statusSyncInProgress) {
|
||||
return;
|
||||
}
|
||||
statusSyncInProgress = true;
|
||||
|
||||
count++;
|
||||
const statusSynced = this.syncBackgroundStatus();
|
||||
if (count % 3 === 0) {
|
||||
// Do a full update every nth time
|
||||
statusSynced.then(() => {
|
||||
if (!statSyncInProgress) {
|
||||
this.syncStats().then(() => {
|
||||
statSyncInProgress = false;
|
||||
});
|
||||
statSyncInProgress = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
statusSynced.finally(() => {
|
||||
statusSyncInProgress = false;
|
||||
});
|
||||
}, 3 * 1000);
|
||||
},
|
||||
resetBOStatsOnStart() {
|
||||
GlobalStats.setBoStats( {
|
||||
is_cancelled: false,
|
||||
is_completed: false,
|
||||
processed_items: 0,
|
||||
failed_items: 0,
|
||||
} );
|
||||
},
|
||||
start() {
|
||||
// Reset boStats.
|
||||
this.resetBOStatsOnStart();
|
||||
|
||||
// Disable UI.
|
||||
this.onStart();
|
||||
|
||||
// Start BO.
|
||||
BO.handle('start').then((res) => {
|
||||
if (res.success) {
|
||||
// Update stats.
|
||||
const updatedStats = this.updateStats(res.data, false);
|
||||
// Show progress bar.
|
||||
this.showProgressBar();
|
||||
this.hookStatusChecks();
|
||||
if ( updatedStats ) {
|
||||
// Render stats.
|
||||
GlobalStats.renderStats();
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showNotice( res, {
|
||||
'showdismiss': true,
|
||||
'autoclose' : false,
|
||||
} );
|
||||
this.cancelBulk();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Initial state when load the Bulk Smush page while BO is running.
|
||||
*/
|
||||
initState() {
|
||||
if (!GlobalStats.getBoStats().in_processing) {
|
||||
return;
|
||||
}
|
||||
// Disable UI.
|
||||
this.onStart();
|
||||
// Start BO.
|
||||
BO.initState().then((res) => {
|
||||
if (res.success) {
|
||||
// Update stats.
|
||||
this.updateStats(res.data, false);
|
||||
// Show progress bar.
|
||||
this.showProgressBar();
|
||||
this.hookStatusChecks();
|
||||
// Maybe update errors.
|
||||
if ( res.data.errors && ! Object.keys( GlobalStats.getErrors() ).length ) {
|
||||
GlobalStats.setErrors( res.data.errors );
|
||||
}
|
||||
// Render stats.
|
||||
GlobalStats.renderStats();
|
||||
} else {
|
||||
WP_Smush.helpers.showNotice( res );
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Cancel.
|
||||
*/
|
||||
cancel() {
|
||||
cancellationInProgress = true;
|
||||
this.setCancelButtonStateToStarted();
|
||||
BO.handle('cancel').then((res) => {
|
||||
if (res.success) {
|
||||
this.cancelBulk();
|
||||
} else {
|
||||
WP_Smush.helpers.showNotice( res );
|
||||
}
|
||||
});
|
||||
},
|
||||
hideProgressBar() {
|
||||
// Hide progress bar.
|
||||
SmushProgress.close().update(0, GlobalStats.getBoStats().total_items);
|
||||
},
|
||||
showProgressBar() {
|
||||
// Reset progress bar.
|
||||
SmushProgress.update(GlobalStats.getBoStats().processed_items, GlobalStats.getBoStats().total_items);
|
||||
// Show progress bar.
|
||||
SmushProgress.show();
|
||||
},
|
||||
/**
|
||||
* Update stats.
|
||||
* @param {Object} newStats Included increment stats and new BO stats.
|
||||
* @param updateGlobal
|
||||
*/
|
||||
updateStats(newStats, updateGlobal) {
|
||||
// Make sure we have processed_stats/errors property (not added by default when start).
|
||||
newStats.global_stats = newStats.global_stats || {};
|
||||
newStats.errors = newStats.errors || {};
|
||||
const {
|
||||
global_stats,
|
||||
errors,
|
||||
...newBoStats
|
||||
} = newStats;
|
||||
if ( ! GlobalStats.isChangedStats( newBoStats ) ) {
|
||||
return false;
|
||||
}
|
||||
// Update BO stats.
|
||||
GlobalStats.setBoStats(newBoStats);
|
||||
if (updateGlobal) {
|
||||
// Update global stats.
|
||||
GlobalStats.setGlobalStats(global_stats);
|
||||
}
|
||||
// Update Errors.
|
||||
GlobalStats.setErrors( errors );
|
||||
return true;
|
||||
},
|
||||
cancelBulk() {
|
||||
// Sync Stats.
|
||||
this.syncStats(() => {
|
||||
if (100 === GlobalStats.getGlobalStats().percent_optimized) {
|
||||
// If the last item was getting processed when the user cancelled then the process might have completed
|
||||
GlobalStats.setBoStats( {
|
||||
is_completed: true
|
||||
} );
|
||||
this.onCompletedBulk();
|
||||
} else {
|
||||
// Update status of boStats.
|
||||
GlobalStats.setBoStats( {
|
||||
is_cancelled: true
|
||||
} );
|
||||
// Reset and hide progress bar.
|
||||
this.onFinish();
|
||||
// Bulk is cancelled, show bulk desc.
|
||||
SmushProgress.showBulkSmushDescription();
|
||||
}
|
||||
|
||||
mixPanel.trackBulkSmushCancel();
|
||||
|
||||
cancellationInProgress = false;
|
||||
});
|
||||
},
|
||||
showCompletedMessage() {
|
||||
// Render completed message.
|
||||
// Show completed message.
|
||||
const processedWrapper = bulkWrapper.querySelector('.wp-smush-all-done');
|
||||
if ( GlobalStats.getBoStats().failed_items ) {
|
||||
let completeMessage = wp_smush_msgs.all_failed;
|
||||
if ( ! this.isFailedAllItems() ) {
|
||||
completeMessage = wp_smush_msgs.error_in_bulk.replace( '{{smushed}}', GlobalStats.getBoStats().total_items - GlobalStats.getBoStats().failed_items )
|
||||
.replace('{{total}}', GlobalStats.getBoStats().total_items )
|
||||
.replace('{{errors}}', GlobalStats.getBoStats().failed_items );
|
||||
}
|
||||
processedWrapper.querySelector('p').innerHTML = completeMessage;
|
||||
processedWrapper.classList.remove('sui-notice-success', 'sui-notice-warning');
|
||||
const noticeType = this.getNoticeType();
|
||||
const noticeIcon = 'warning' === noticeType ? 'info' : 'check-tick';
|
||||
const iconElement = processedWrapper.querySelector('.sui-notice-icon');
|
||||
processedWrapper.classList.add( 'sui-notice-' + noticeType );
|
||||
iconElement.classList.remove('sui-icon-check-tick', 'sui-icon-info');
|
||||
iconElement.classList.add( 'sui-icon-' + noticeIcon );
|
||||
} else {
|
||||
processedWrapper.querySelector('p').innerHTML = wp_smush_msgs.all_smushed;
|
||||
}
|
||||
processedWrapper.classList.remove('sui-hidden');
|
||||
},
|
||||
isFailedAllItems() {
|
||||
return GlobalStats.getBoStats().failed_items === GlobalStats.getBoStats().total_items;
|
||||
},
|
||||
getNoticeType() {
|
||||
return this.isFailedAllItems() ? 'warning' : 'success';
|
||||
},
|
||||
onCompletedBulk() {
|
||||
// Reset and hide progress bar.
|
||||
this.onFinish();
|
||||
// Bulk is completed, hide bulk desc.
|
||||
SmushProgress.hideBulkSmushDescription();
|
||||
// Show completed message.
|
||||
this.showCompletedMessage();
|
||||
|
||||
// Reset the progress when we finish so the next smushing starts from zero.
|
||||
SmushProgress.update(0, GlobalStats.getBoStats().total_items);
|
||||
},
|
||||
completeBulk() {
|
||||
// Sync Stats.
|
||||
this.syncStats(() => this.onCompletedBulk());
|
||||
},
|
||||
syncStats(onComplete = () => false) {
|
||||
return BO.handle('getStats').then((res) => {
|
||||
if ( res.success ) {
|
||||
const responseErrors = res.data.errors || {};
|
||||
this.updateStats( { global_stats: res.data, errors: responseErrors }, true );
|
||||
GlobalStats.renderStats();
|
||||
if ( res.data.content ) {
|
||||
$('#wp-smush-bulk-content').innerHTML = res.data.content;
|
||||
}
|
||||
onComplete();
|
||||
} else {
|
||||
WP_Smush.helpers.showNotice( res );
|
||||
}
|
||||
}).catch( (error) => console.log('error', error));
|
||||
},
|
||||
syncBackgroundStatus() {
|
||||
return BO.handle('getStatus').then((res) => {
|
||||
if ((res.data || {}).in_process_notice) {
|
||||
SmushProgress.setNotice( res.data.in_process_notice );
|
||||
}
|
||||
|
||||
if (res.success) {
|
||||
// Update stats.
|
||||
if ( this.updateStats(res.data, false) ) {
|
||||
// Update progress bar.
|
||||
SmushProgress.update(GlobalStats.getBoStats().processed_items, GlobalStats.getBoStats().total_items);
|
||||
|
||||
if (! GlobalStats.getBoStats().is_cancelled && ! GlobalStats.getBoStats().is_completed) {
|
||||
// Render stats.
|
||||
GlobalStats.renderStats();
|
||||
}
|
||||
}
|
||||
|
||||
if (GlobalStats.getBoStats().is_cancelled && !cancellationInProgress) {
|
||||
// Cancelled on server side
|
||||
this.cancelBulk();
|
||||
} else if (GlobalStats.getBoStats().is_completed) {
|
||||
this.completeBulk();
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showNotice( res );
|
||||
}
|
||||
});
|
||||
},
|
||||
onStart() {
|
||||
// Disable btn.
|
||||
startBtn.setAttribute('disabled', '');
|
||||
// Disable re-check images.
|
||||
reScanImagesButton && reScanImagesButton.setAttribute('disabled', '');
|
||||
$('.wp-smush-restore').setAttribute('disabled', '');
|
||||
// Show upsell cdn.
|
||||
UpsellManger.maybeShowCDNUpsellForPreSiteOnStart();
|
||||
|
||||
this.setCancelButtonStateToInitial();
|
||||
},
|
||||
onFinish() {
|
||||
// Clear interval.
|
||||
if (intervalHandle) {
|
||||
clearInterval(intervalHandle);
|
||||
intervalHandle = 0;
|
||||
}
|
||||
|
||||
// Disable btn.
|
||||
startBtn.removeAttribute('disabled');
|
||||
// Reset and hide Progress Bar.
|
||||
this.hideProgressBar();
|
||||
// Disable re-check images.
|
||||
reScanImagesButton && reScanImagesButton.removeAttribute('disabled', '');
|
||||
$('.wp-smush-restore').removeAttribute('disabled', '');
|
||||
|
||||
// Show upsell cdn.
|
||||
UpsellManger.maybeShowCDNUpsellForPreSiteOnCompleted();
|
||||
},
|
||||
init() {
|
||||
if (!startBtn) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start BO.
|
||||
startBtn.onclick = () => {
|
||||
const requiredScanMedia = startBtn.classList.contains('wp-smush-scan-and-bulk-smush');
|
||||
if ( requiredScanMedia ) {
|
||||
return;
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
|
||||
// If BO is running, initial new state.
|
||||
this.initState();
|
||||
},
|
||||
setCancelButtonStateToInitial() {
|
||||
SmushProgress.setCancelButtonLabel( wp_smush_msgs.cancel );
|
||||
SmushProgress.setOnCancelCallback( this.cancel.bind(this) );
|
||||
},
|
||||
setCancelButtonStateToStarted() {
|
||||
SmushProgress.setCancelButtonLabel( wp_smush_msgs.cancelling );
|
||||
SmushProgress.setOnCancelCallback( () => false );
|
||||
},
|
||||
}
|
||||
})();
|
||||
// Run.
|
||||
BackgroundSmush && BackgroundSmush.init();
|
||||
/**
|
||||
* For globalStats, we will need to update it on reload and after re-checking images,
|
||||
* and on finish the BO.
|
||||
* 1. On finish, we handled via BackgroundSmush.syncStats -> BackgroundSmush.updateStats
|
||||
* 2. On reload or after re-checking images, we need to update globalStats from global variable:
|
||||
* window.wp_smushit_data
|
||||
*/
|
||||
// Update global stats after re-checking images.
|
||||
document.addEventListener('wpSmushAfterRecheckImages', function(){
|
||||
GlobalStats.updateGlobalStatsFromSmushScriptData();
|
||||
});
|
||||
|
||||
document.addEventListener('backgroundBulkSmushOnScanCompleted', function(){
|
||||
if ( ! BackgroundSmush ) {
|
||||
return;
|
||||
}
|
||||
GlobalStats.setBoStats({
|
||||
in_processing: true,
|
||||
});
|
||||
BackgroundSmush.initState();
|
||||
});
|
||||
})();
|
276
wp-content/plugins/wp-smushit/_src/js/modules/bulk-restore.js
Normal file
276
wp-content/plugins/wp-smushit/_src/js/modules/bulk-restore.js
Normal file
@ -0,0 +1,276 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
/* global _ */
|
||||
|
||||
import MixPanel from "../mixpanel";
|
||||
|
||||
/**
|
||||
* Bulk restore JavaScript code.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Bulk restore modal.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
WP_Smush.restore = {
|
||||
modal: document.getElementById('smush-restore-images-dialog'),
|
||||
contentContainer: document.getElementById('smush-bulk-restore-content'),
|
||||
settings: {
|
||||
slide: 'start', // start, progress or finish.
|
||||
success: 0,
|
||||
errors: [],
|
||||
},
|
||||
items: [], // total items, 1 item = 1 step.
|
||||
success: [], // successful items restored.
|
||||
errors: [], // failed items.
|
||||
currentStep: 0,
|
||||
totalSteps: 0,
|
||||
|
||||
/**
|
||||
* Init module.
|
||||
*/
|
||||
init() {
|
||||
if (!this.modal) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings = {
|
||||
slide: 'start',
|
||||
success: 0,
|
||||
errors: [],
|
||||
};
|
||||
|
||||
this.mixPanel = MixPanel.getInstance();
|
||||
|
||||
this.resetModalWidth();
|
||||
this.renderTemplate();
|
||||
|
||||
// Show the modal.
|
||||
|
||||
window.SUI.openModal(
|
||||
'smush-restore-images-dialog',
|
||||
'wpbody-content',
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the template, register new listeners.
|
||||
*/
|
||||
renderTemplate() {
|
||||
const template = WP_Smush.onboarding.template('smush-bulk-restore');
|
||||
const content = template(this.settings);
|
||||
|
||||
if (content) {
|
||||
this.contentContainer.innerHTML = content;
|
||||
}
|
||||
|
||||
this.bindSubmit();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset modal width.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*/
|
||||
resetModalWidth() {
|
||||
this.modal.style.maxWidth = '460px';
|
||||
this.modal.querySelector('.sui-box').style.maxWidth = '460px';
|
||||
},
|
||||
|
||||
/**
|
||||
* Catch "Finish setup wizard" button click.
|
||||
*/
|
||||
bindSubmit() {
|
||||
const confirmButton = this.modal.querySelector(
|
||||
'button[id="smush-bulk-restore-button"]'
|
||||
);
|
||||
const self = this;
|
||||
|
||||
if (confirmButton) {
|
||||
confirmButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
self.resetModalWidth();
|
||||
|
||||
self.settings = { slide: 'progress' };
|
||||
self.errors = [];
|
||||
|
||||
self.renderTemplate();
|
||||
self.initScan();
|
||||
|
||||
self.mixPanel.track('Bulk Restore Triggered');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel the bulk restore.
|
||||
*/
|
||||
cancel() {
|
||||
if (
|
||||
'start' === this.settings.slide ||
|
||||
'finish' === this.settings.slide
|
||||
) {
|
||||
// Hide the modal.
|
||||
window.SUI.closeModal();
|
||||
} else {
|
||||
this.updateProgressBar(true);
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update progress bar during directory smush.
|
||||
*
|
||||
* @param {boolean} cancel Cancel status.
|
||||
*/
|
||||
updateProgressBar(cancel = false) {
|
||||
let progress = 0;
|
||||
if (0 < this.currentStep) {
|
||||
progress = Math.min(
|
||||
Math.round((this.currentStep * 100) / this.totalSteps),
|
||||
99
|
||||
);
|
||||
}
|
||||
|
||||
if (progress > 100) {
|
||||
progress = 100;
|
||||
}
|
||||
|
||||
// Update progress bar
|
||||
this.modal.querySelector('.sui-progress-text span').innerHTML =
|
||||
progress + '%';
|
||||
this.modal.querySelector('.sui-progress-bar span').style.width =
|
||||
progress + '%';
|
||||
|
||||
const statusDiv = this.modal.querySelector(
|
||||
'.sui-progress-state-text'
|
||||
);
|
||||
if (progress >= 90) {
|
||||
statusDiv.innerHTML = 'Finalizing...';
|
||||
} else if (cancel) {
|
||||
statusDiv.innerHTML = 'Cancelling...';
|
||||
} else {
|
||||
statusDiv.innerHTML =
|
||||
this.currentStep +
|
||||
'/' +
|
||||
this.totalSteps +
|
||||
' ' +
|
||||
'images restored';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* First step in bulk restore - get the bulk attachment count.
|
||||
*/
|
||||
initScan() {
|
||||
const self = this;
|
||||
const _nonce = document.getElementById('_wpnonce');
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', ajaxurl + '?action=get_image_count', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if (200 === xhr.status) {
|
||||
const res = JSON.parse(xhr.response);
|
||||
if ('undefined' !== typeof res.data.items) {
|
||||
self.items = res.data.items;
|
||||
self.totalSteps = res.data.items.length;
|
||||
self.step();
|
||||
}
|
||||
} else {
|
||||
window.console.log(
|
||||
'Request failed. Returned status of ' + xhr.status
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send('_ajax_nonce=' + _nonce.value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute a scan step recursively
|
||||
*/
|
||||
step() {
|
||||
const self = this;
|
||||
const _nonce = document.getElementById('_wpnonce');
|
||||
|
||||
if (0 < this.items.length) {
|
||||
const item = this.items.pop();
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', ajaxurl + '?action=restore_step', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
this.currentStep++;
|
||||
|
||||
if (200 === xhr.status) {
|
||||
const res = JSON.parse(xhr.response);
|
||||
const data = ((res || {}).data || {});
|
||||
if (data.success) {
|
||||
self.success.push(item);
|
||||
} else {
|
||||
self.errors.push({
|
||||
id: item,
|
||||
src: data.src || "Error",
|
||||
thumb: data.thumb,
|
||||
link: data.link,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.updateProgressBar();
|
||||
self.step();
|
||||
};
|
||||
xhr.send('item=' + item + '&_ajax_nonce=' + _nonce.value);
|
||||
} else {
|
||||
// Finish.
|
||||
this.settings = {
|
||||
slide: 'finish',
|
||||
success: this.success.length,
|
||||
errors: this.errors,
|
||||
total: this.totalSteps,
|
||||
};
|
||||
|
||||
self.renderTemplate();
|
||||
if (0 < this.errors.length) {
|
||||
this.modal.style.maxWidth = '660px';
|
||||
this.modal.querySelector('.sui-box').style.maxWidth =
|
||||
'660px';
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Template function (underscores based).
|
||||
*
|
||||
* @type {Function}
|
||||
*/
|
||||
WP_Smush.restore.template = _.memoize((id) => {
|
||||
let compiled;
|
||||
const options = {
|
||||
evaluate: /<#([\s\S]+?)#>/g,
|
||||
interpolate: /{{{([\s\S]+?)}}}/g,
|
||||
escape: /{{([^}]+?)}}(?!})/g,
|
||||
variable: 'data',
|
||||
};
|
||||
|
||||
return (data) => {
|
||||
_.templateSettings = options;
|
||||
compiled =
|
||||
compiled || _.template(document.getElementById(id).innerHTML);
|
||||
return compiled(data);
|
||||
};
|
||||
});
|
||||
})();
|
149
wp-content/plugins/wp-smushit/_src/js/modules/bulk-smush.js
Normal file
149
wp-content/plugins/wp-smushit/_src/js/modules/bulk-smush.js
Normal file
@ -0,0 +1,149 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Bulk Smush functionality.
|
||||
*
|
||||
* @since 2.9.0 Moved from admin.js
|
||||
*/
|
||||
|
||||
import Smush from '../smush/smush';
|
||||
import Fetcher from '../utils/fetcher';
|
||||
import SmushProcess from '../common/progressbar';
|
||||
|
||||
( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.bulk = {
|
||||
init() {
|
||||
this.onClickBulkSmushNow();
|
||||
this.onClickIgnoreImage();
|
||||
this.onClickIgnoreAllImages();
|
||||
this.onScanCompleted();
|
||||
},
|
||||
onClickBulkSmushNow() {
|
||||
/**
|
||||
* Handle the Bulk Smush/Bulk re-Smush button click.
|
||||
*/
|
||||
$( '.wp-smush-all' ).on( 'click', function( e ) {
|
||||
const bulkSmushButton = $(this);
|
||||
if ( bulkSmushButton.hasClass('wp-smush-scan-and-bulk-smush') ) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
WP_Smush.bulk.ajaxBulkSmushStart( bulkSmushButton );
|
||||
} );
|
||||
},
|
||||
ajaxBulkSmushStart( bulkSmushButton ) {
|
||||
bulkSmushButton = bulkSmushButton || $( '#wp-smush-bulk-content .wp-smush-all' );
|
||||
// Check for IDs, if there is none (unsmushed or lossless), don't call Smush function.
|
||||
/** @param {Array} wp_smushit_data.unsmushed */
|
||||
if (
|
||||
'undefined' === typeof window.wp_smushit_data ||
|
||||
( 0 === window.wp_smushit_data.unsmushed.length &&
|
||||
0 === window.wp_smushit_data.resmush.length )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// Disable re-Smush and scan button.
|
||||
// TODO: refine what is disabled.
|
||||
$(
|
||||
'.wp-resmush.wp-smush-action, .wp-smush-scan, .wp-smush-all:not(.sui-progress-close), a.wp-smush-lossy-enable, button.wp-smush-resize-enable, button#save-settings-button'
|
||||
).prop( 'disabled', true );
|
||||
|
||||
if ( bulkSmushButton.hasClass('wp-smush-resume-bulk-smush') && this.bulkSmush ) {
|
||||
this.resumeBulkSmush();
|
||||
return;
|
||||
}
|
||||
|
||||
this.bulkSmush = new Smush( bulkSmushButton, true );
|
||||
SmushProcess.setOnCancelCallback( () => {
|
||||
this.bulkSmush.cancelAjax()
|
||||
}).update( 0, this.bulkSmush.ids.length ).show();
|
||||
|
||||
// Show upsell cdn.
|
||||
this.maybeShowCDNUpsellForPreSiteOnStart();
|
||||
|
||||
// Run bulk Smush.
|
||||
this.bulkSmush.run();
|
||||
},
|
||||
resumeBulkSmush() {
|
||||
SmushProcess.disableExceedLimitMode();
|
||||
SmushProcess.hideBulkSmushDescription();
|
||||
this.bulkSmush.onStart();
|
||||
this.bulkSmush.callAjax();
|
||||
},
|
||||
onClickIgnoreImage() {
|
||||
/**
|
||||
* Ignore file from bulk Smush.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
$( 'body' ).on( 'click', '.smush-ignore-image', function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
const self = $( this );
|
||||
|
||||
self.prop( 'disabled', true );
|
||||
self.attr( 'data-tooltip' );
|
||||
self.removeClass( 'sui-tooltip' );
|
||||
$.post( ajaxurl, {
|
||||
action: 'ignore_bulk_image',
|
||||
id: self.attr( 'data-id' ),
|
||||
_ajax_nonce: wp_smush_msgs.nonce,
|
||||
} ).done( ( response ) => {
|
||||
if ( self.is( 'a' ) && response.success && 'undefined' !== typeof response.data.html ) {
|
||||
if( self.closest('.smush-status-links') ) {
|
||||
self.closest('.smush-status-links').parent().html( response.data.html );
|
||||
} else if (e.target.closest( '.smush-bulk-error-row' ) ){
|
||||
self.addClass('disabled');
|
||||
e.target.closest( '.smush-bulk-error-row' ).style.opacity = 0.5;
|
||||
}
|
||||
}
|
||||
} );
|
||||
} );
|
||||
},
|
||||
onClickIgnoreAllImages() {
|
||||
/**
|
||||
* Ignore file from bulk Smush.
|
||||
*
|
||||
* @since 3.12.0
|
||||
*/
|
||||
const ignoreAll = document.querySelector('.wp_smush_ignore_all_failed_items');
|
||||
if ( ignoreAll ) {
|
||||
ignoreAll.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
e.target.setAttribute('disabled','');
|
||||
e.target.style.cursor = 'progress';
|
||||
const type = e.target.dataset.type || null;
|
||||
e.target.classList.remove('sui-tooltip');
|
||||
Fetcher.smush.ignoreAll(type).then((res) => {
|
||||
if ( res.success ) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
e.target.style.cursor = 'pointer';
|
||||
e.target.removeAttribute('disabled');
|
||||
WP_Smush.helpers.showNotice( res );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
onScanCompleted() {
|
||||
document.addEventListener('ajaxBulkSmushOnScanCompleted', (e) => {
|
||||
this.ajaxBulkSmushStart();
|
||||
});
|
||||
},
|
||||
maybeShowCDNUpsellForPreSiteOnStart: () => {
|
||||
// Show upsell cdn.
|
||||
const upsell_cdn = document.querySelector('.wp-smush-upsell-cdn');
|
||||
if ( upsell_cdn ) {
|
||||
upsell_cdn.classList.remove('sui-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
WP_Smush.bulk.init();
|
||||
} )( jQuery );
|
279
wp-content/plugins/wp-smushit/_src/js/modules/directory-smush.js
Normal file
279
wp-content/plugins/wp-smushit/_src/js/modules/directory-smush.js
Normal file
@ -0,0 +1,279 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Directory Smush module JavaScript code.
|
||||
*
|
||||
* @since 2.8.1 Separated from admin.js into dedicated file.
|
||||
*/
|
||||
|
||||
import { createTree } from 'jquery.fancytree';
|
||||
import Scanner from '../smush/directory-scanner';
|
||||
|
||||
( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.directory = {
|
||||
selected: [],
|
||||
tree: [],
|
||||
wp_smush_msgs: [],
|
||||
triggered: false,
|
||||
|
||||
init() {
|
||||
const self = this,
|
||||
progressDialog = $( '#wp-smush-progress-dialog' );
|
||||
|
||||
let totalSteps = 0,
|
||||
currentScanStep = 0;
|
||||
|
||||
// Make sure directory smush vars are set.
|
||||
if ( typeof window.wp_smushit_data.dir_smush !== 'undefined' ) {
|
||||
totalSteps = window.wp_smushit_data.dir_smush.totalSteps;
|
||||
currentScanStep =
|
||||
window.wp_smushit_data.dir_smush.currentScanStep;
|
||||
}
|
||||
|
||||
// Init image scanner.
|
||||
this.scanner = new Scanner( totalSteps, currentScanStep );
|
||||
|
||||
/**
|
||||
* Smush translation strings.
|
||||
*
|
||||
* @param {Array} wp_smush_msgs
|
||||
*/
|
||||
this.wp_smush_msgs = window.wp_smush_msgs || {};
|
||||
|
||||
/**
|
||||
* Open the "Select Smush directory" modal.
|
||||
*/
|
||||
$( 'button.wp-smush-browse, a#smush-directory-open-modal' ).on(
|
||||
'click',
|
||||
function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
if ( $( e.currentTarget ).hasClass( 'wp-smush-browse' ) ) {
|
||||
// Hide all the notices.
|
||||
$( 'div.wp-smush-scan-result div.wp-smush-notice' ).hide();
|
||||
|
||||
// Remove notice.
|
||||
$( 'div.wp-smush-info' ).remove();
|
||||
}
|
||||
|
||||
window.SUI.openModal(
|
||||
'wp-smush-list-dialog',
|
||||
e.currentTarget,
|
||||
$(
|
||||
'#wp-smush-list-dialog .sui-box-header [data-modal-close]'
|
||||
)[0],
|
||||
true
|
||||
);
|
||||
//Display File tree for Directory Smush
|
||||
self.initFileTree();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Smush images: Smush in Choose Directory modal clicked
|
||||
*/
|
||||
$( '#wp-smush-select-dir' ).on( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
$( 'div.wp-smush-list-dialog div.sui-box-body' ).css( {
|
||||
opacity: '0.8',
|
||||
} );
|
||||
$( 'div.wp-smush-list-dialog div.sui-box-body a' ).off(
|
||||
'click'
|
||||
);
|
||||
|
||||
const button = $( this );
|
||||
|
||||
// Display the spinner.
|
||||
button.addClass('sui-button-onload');
|
||||
|
||||
const selectedFolders = self.tree.getSelectedNodes();
|
||||
|
||||
const paths = [];
|
||||
selectedFolders.forEach( function( folder ) {
|
||||
paths.push( folder.key );
|
||||
} );
|
||||
|
||||
// Send a ajax request to get a list of all the image files
|
||||
const param = {
|
||||
action: 'image_list',
|
||||
smush_path: paths,
|
||||
image_list_nonce: $(
|
||||
'input[name="image_list_nonce"]'
|
||||
).val(),
|
||||
};
|
||||
|
||||
$.post( ajaxurl, param, function( response ) {
|
||||
if ( response.success ) {
|
||||
// Close the modal.
|
||||
window.SUI.closeModal();
|
||||
|
||||
self.scanner = new Scanner( response.data, 0 );
|
||||
self.showProgressDialog( response.data );
|
||||
self.scanner.scan();
|
||||
} else {
|
||||
// Remove the spinner.
|
||||
button.removeClass('sui-button-onload');
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-ajax-notice',
|
||||
response.data.message,
|
||||
{ type: 'warning' }
|
||||
);
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Cancel scan.
|
||||
*/
|
||||
progressDialog.on(
|
||||
'click',
|
||||
'#cancel-directory-smush, #dialog-close-div, .wp-smush-cancel-dir',
|
||||
function( e ) {
|
||||
e.preventDefault();
|
||||
// Display the spinner
|
||||
$( '.wp-smush-cancel-dir' ).addClass( 'sui-button-onload' );
|
||||
self.scanner
|
||||
.cancel()
|
||||
.done(
|
||||
() =>
|
||||
( window.location.href =
|
||||
self.wp_smush_msgs.directory_url )
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Continue scan.
|
||||
*/
|
||||
progressDialog.on(
|
||||
'click',
|
||||
'.sui-icon-play, .wp-smush-resume-scan',
|
||||
function( e ) {
|
||||
e.preventDefault();
|
||||
self.scanner.resume();
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Check to see if we should open the directory module.
|
||||
* Used to redirect from dashboard page.
|
||||
*
|
||||
* @since 3.8.6
|
||||
*/
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams( queryString );
|
||||
if ( urlParams.has( 'start' ) && ! this.triggered ) {
|
||||
this.triggered = true;
|
||||
$( 'button.wp-smush-browse' ).trigger( 'click' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Init fileTree.
|
||||
*/
|
||||
initFileTree() {
|
||||
const self = this,
|
||||
smushButton = $( 'button#wp-smush-select-dir' ),
|
||||
ajaxSettings = {
|
||||
type: 'GET',
|
||||
url: ajaxurl,
|
||||
data: {
|
||||
action: 'smush_get_directory_list',
|
||||
list_nonce: $( 'input[name="list_nonce"]' ).val(),
|
||||
},
|
||||
cache: false,
|
||||
};
|
||||
|
||||
// Object already defined.
|
||||
if ( Object.entries( self.tree ).length > 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.tree = createTree( '.wp-smush-list-dialog .content', {
|
||||
autoCollapse: true, // Automatically collapse all siblings, when a node is expanded
|
||||
clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand, 4:activate (dblclick expands)
|
||||
checkbox: true, // Show checkboxes
|
||||
debugLevel: 0, // 0:quiet, 1:errors, 2:warnings, 3:infos, 4:debug
|
||||
selectMode: 3, // 1:single, 2:multi, 3:multi-hier
|
||||
tabindex: '0', // Whole tree behaves as one single control
|
||||
keyboard: true, // Support keyboard navigation
|
||||
quicksearch: true, // Navigate to next node by typing the first letters
|
||||
source: ajaxSettings,
|
||||
lazyLoad: ( event, data ) => {
|
||||
data.result = new Promise( function( resolve, reject ) {
|
||||
ajaxSettings.data.dir = data.node.key;
|
||||
$.ajax( ajaxSettings )
|
||||
.done( ( response ) => resolve( response ) )
|
||||
.fail( reject );
|
||||
} );
|
||||
},
|
||||
loadChildren: ( event, data ) =>
|
||||
data.node.fixSelection3AfterClick(), // Apply parent's state to new child nodes:
|
||||
select: () =>
|
||||
smushButton.prop(
|
||||
'disabled',
|
||||
! +self.tree.getSelectedNodes().length
|
||||
),
|
||||
init: () => smushButton.prop( 'disabled', true ),
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Show progress dialog.
|
||||
*
|
||||
* @param {number} items Number of items in the scan.
|
||||
*/
|
||||
showProgressDialog( items ) {
|
||||
// Update items status and show the progress dialog..
|
||||
$( '.wp-smush-progress-dialog .sui-progress-state-text' ).html(
|
||||
'0/' + items + ' ' + self.wp_smush_msgs.progress_smushed
|
||||
);
|
||||
|
||||
window.SUI.openModal(
|
||||
'wp-smush-progress-dialog',
|
||||
'dialog-close-div',
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update progress bar during directory smush.
|
||||
*
|
||||
* @param {number} progress Current progress in percent.
|
||||
* @param {boolean} cancel Cancel status.
|
||||
*/
|
||||
updateProgressBar( progress, cancel = false ) {
|
||||
if ( progress > 100 ) {
|
||||
progress = 100;
|
||||
}
|
||||
|
||||
// Update progress bar
|
||||
$( '.sui-progress-block .sui-progress-text span' ).text(
|
||||
progress + '%'
|
||||
);
|
||||
$( '.sui-progress-block .sui-progress-bar span' ).width(
|
||||
progress + '%'
|
||||
);
|
||||
|
||||
if ( progress >= 90 ) {
|
||||
$( '.sui-progress-state .sui-progress-state-text' ).text(
|
||||
'Finalizing...'
|
||||
);
|
||||
}
|
||||
|
||||
if ( cancel ) {
|
||||
$( '.sui-progress-state .sui-progress-state-text' ).text(
|
||||
'Cancelling...'
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
WP_Smush.directory.init();
|
||||
}( jQuery ) );
|
298
wp-content/plugins/wp-smushit/_src/js/modules/helpers.js
Normal file
298
wp-content/plugins/wp-smushit/_src/js/modules/helpers.js
Normal file
@ -0,0 +1,298 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
/* global wp_smush_msgs */
|
||||
|
||||
/**
|
||||
* Helpers functions.
|
||||
*
|
||||
* @since 2.9.0 Moved from admin.js
|
||||
*/
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.helpers = {
|
||||
init: () => {},
|
||||
cacheUpsellErrorCodes: [],
|
||||
|
||||
/**
|
||||
* Convert bytes to human-readable form.
|
||||
*
|
||||
* @param {number} a Bytes
|
||||
* @param {number} b Number of digits
|
||||
* @return {*} Formatted Bytes
|
||||
*/
|
||||
formatBytes: ( a, b ) => {
|
||||
const thresh = 1024,
|
||||
units = [ 'KB', 'MB', 'GB', 'TB', 'PB' ];
|
||||
|
||||
if ( Math.abs( a ) < thresh ) {
|
||||
return a + ' B';
|
||||
}
|
||||
|
||||
let u = -1;
|
||||
|
||||
do {
|
||||
a /= thresh;
|
||||
++u;
|
||||
} while ( Math.abs( a ) >= thresh && u < units.length - 1 );
|
||||
|
||||
return a.toFixed( b ) + ' ' + units[ u ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Get size from a string.
|
||||
*
|
||||
* @param {string} formattedSize Formatter string
|
||||
* @return {*} Formatted Bytes
|
||||
*/
|
||||
getSizeFromString: ( formattedSize ) => {
|
||||
return formattedSize.replace( /[a-zA-Z]/g, '' ).trim();
|
||||
},
|
||||
|
||||
/**
|
||||
* Get type from formatted string.
|
||||
*
|
||||
* @param {string} formattedSize Formatted string
|
||||
* @return {*} Formatted Bytes
|
||||
*/
|
||||
getFormatFromString: ( formattedSize ) => {
|
||||
return formattedSize.replace( /[0-9.]/g, '' ).trim();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stackoverflow: http://stackoverflow.com/questions/1726630/formatting-a-number-with-exactly-two-decimals-in-javascript
|
||||
*
|
||||
* @param {number} num
|
||||
* @param {number} decimals
|
||||
* @return {number} Number
|
||||
*/
|
||||
precise_round: ( num, decimals ) => {
|
||||
const sign = num >= 0 ? 1 : -1;
|
||||
// Keep the percentage below 100.
|
||||
num = num > 100 ? 100 : num;
|
||||
return (
|
||||
Math.round( num * Math.pow( 10, decimals ) + sign * 0.001 ) /
|
||||
Math.pow( 10, decimals )
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a floating error message using the #wp-smush-ajax-notice container.
|
||||
*
|
||||
* @since 3.8.0
|
||||
*
|
||||
* @param {string} message
|
||||
*/
|
||||
showErrorNotice: ( message ) => {
|
||||
if ( 'undefined' === typeof message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const noticeMessage = `<p>${ message }</p>`,
|
||||
noticeOptions = {
|
||||
type: 'error',
|
||||
icon: 'info',
|
||||
};
|
||||
|
||||
SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions );
|
||||
|
||||
const loadingButton = document.querySelector( '.sui-button-onload' );
|
||||
if ( loadingButton ) {
|
||||
loadingButton.classList.remove( 'sui-button-onload' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset settings.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*/
|
||||
resetSettings: () => {
|
||||
const _nonce = document.getElementById( 'wp_smush_reset' );
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=reset_settings', true );
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
const res = JSON.parse( xhr.response );
|
||||
if ( 'undefined' !== typeof res.success && res.success ) {
|
||||
window.location.href = wp_smush_msgs.smush_url;
|
||||
}
|
||||
} else {
|
||||
window.console.log(
|
||||
'Request failed. Returned status of ' + xhr.status
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send( '_ajax_nonce=' + _nonce.value );
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare error row. Will only allow to hide errors for WP media attachments (not nextgen).
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @since 3.12.0 Moved from Smush.
|
||||
*
|
||||
* @param {string} errorMsg Error message.
|
||||
* @param {string} fileName File name.
|
||||
* @param {string} thumbnail Thumbnail for image (if available).
|
||||
* @param {number} id Image ID.
|
||||
* @param {string} type Smush type: media or netxgen.
|
||||
* @param {string} errorCode Error code.
|
||||
*
|
||||
* @return {string} Row with error.
|
||||
*/
|
||||
prepareBulkSmushErrorRow: (errorMsg, fileName, thumbnail, id, type, errorCode) => {
|
||||
const thumbDiv =
|
||||
thumbnail && 'undefined' !== typeof thumbnail ?
|
||||
`<img class="attachment-thumbnail" src="${thumbnail}" />` :
|
||||
'<i class="sui-icon-photo-picture" aria-hidden="true"></i>';
|
||||
const editLink = window.wp_smush_msgs.edit_link.replace('{{id}}', id);
|
||||
fileName =
|
||||
'undefined' === fileName || 'undefined' === typeof fileName ?
|
||||
'undefined' :
|
||||
fileName;
|
||||
|
||||
let tableDiv =
|
||||
`<div class="smush-bulk-error-row" data-error-code="${errorCode}">
|
||||
<div class="smush-bulk-image-data">
|
||||
<div class="smush-bulk-image-title">
|
||||
${ thumbDiv }
|
||||
<span class="smush-image-name">
|
||||
<a href="${editLink}">${fileName}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="smush-image-error">
|
||||
${errorMsg}
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
if ('media' === type) {
|
||||
tableDiv +=
|
||||
`<div class="smush-bulk-image-actions">
|
||||
<a href="javascript:void(0)" class="sui-tooltip sui-tooltip-constrained sui-tooltip-left smush-ignore-image" data-tooltip="${window.wp_smush_msgs.error_ignore}" data-id="${id}">
|
||||
${window.wp_smush_msgs.btn_ignore}
|
||||
</a>
|
||||
<a class="smush-link-detail" href="${editLink}">
|
||||
${window.wp_smush_msgs.view_detail}
|
||||
</a>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
tableDiv += '</div>';
|
||||
|
||||
tableDiv += WP_Smush.helpers.upsellWithError( errorCode );
|
||||
|
||||
return tableDiv;
|
||||
},
|
||||
cacheUpsellErrorCode( errorCode ) {
|
||||
this.cacheUpsellErrorCodes.push( errorCode );
|
||||
},
|
||||
/**
|
||||
* Get upsell base on error code.
|
||||
* @param {string} errorCode Error code.
|
||||
* @returns {string}
|
||||
*/
|
||||
upsellWithError(errorCode) {
|
||||
if (
|
||||
!errorCode
|
||||
|| !window.wp_smush_msgs['error_' + errorCode]
|
||||
|| this.isUpsellRendered( errorCode )
|
||||
) {
|
||||
return '';
|
||||
}
|
||||
this.cacheRenderedUpsell( errorCode );
|
||||
|
||||
return '<div class="smush-bulk-error-row smush-error-upsell">' +
|
||||
'<div class="smush-bulk-image-title">' +
|
||||
'<span class="smush-image-error">' +
|
||||
window.wp_smush_msgs['error_' + errorCode] +
|
||||
'</span>' +
|
||||
'</div></div>';
|
||||
},
|
||||
// Do not use arrow function to use `this`.
|
||||
isUpsellRendered( errorCode ) {
|
||||
return this.cacheUpsellErrorCodes.includes( errorCode );
|
||||
},
|
||||
// Do not use arrow function to use `this`.
|
||||
cacheRenderedUpsell( errorCode ) {
|
||||
this.cacheUpsellErrorCodes.push( errorCode );
|
||||
},
|
||||
/**
|
||||
* Get error message from Ajax response or Error.
|
||||
* @param {Object} resp
|
||||
*/
|
||||
getErrorMessage: ( resp ) => {
|
||||
return resp.message || resp.data && resp.data.message ||
|
||||
resp.responseJSON && resp.responseJSON.data && resp.responseJSON.data.message ||
|
||||
window.wp_smush_msgs.generic_ajax_error ||
|
||||
resp.status && 'Request failed. Returned status of ' + resp.status
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a floating message from response,
|
||||
* using the #wp-smush-ajax-notice container.
|
||||
*
|
||||
* @param {Object|string} notice
|
||||
* @param {Object} noticeOptions
|
||||
*/
|
||||
showNotice: function( notice, noticeOptions ) {
|
||||
let message;
|
||||
if ( 'object' === typeof notice ) {
|
||||
message = this.getErrorMessage( notice );
|
||||
} else {
|
||||
message = notice;
|
||||
}
|
||||
|
||||
if ( ! message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
noticeOptions = noticeOptions || {};
|
||||
noticeOptions = Object.assign({
|
||||
showdismiss: false,
|
||||
autoclose: true,
|
||||
},noticeOptions);
|
||||
noticeOptions = {
|
||||
type: noticeOptions.type || 'error',
|
||||
icon: noticeOptions.icon || ( 'success' === noticeOptions.type ? 'check-tick' : 'info' ),
|
||||
dismiss: {
|
||||
show: noticeOptions.showdismiss,
|
||||
label: window.wp_smush_msgs.noticeDismiss,
|
||||
tooltip: window.wp_smush_msgs.noticeDismissTooltip,
|
||||
},
|
||||
autoclose: {
|
||||
show: noticeOptions.autoclose
|
||||
}
|
||||
};
|
||||
|
||||
const noticeMessage = `<p>${ message }</p>`;
|
||||
|
||||
SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions );
|
||||
return Promise.resolve( '#wp-smush-ajax-notice' );
|
||||
},
|
||||
closeNotice() {
|
||||
window.SUI.closeNotice( 'wp-smush-ajax-notice' );
|
||||
},
|
||||
renderActivationCDNNotice: function( noticeMessage ) {
|
||||
const animatedNotice = document.getElementById('wp-smush-animated-upsell-notice');
|
||||
if ( animatedNotice ) {
|
||||
return;
|
||||
}
|
||||
const upsellHtml = `<div class="sui-notice sui-notice-info sui-margin-top" id="wp-smush-animated-upsell-notice">
|
||||
<div class="sui-notice-content">
|
||||
<div class="sui-notice-message">
|
||||
<i class="sui-notice-icon sui-icon-info" aria-hidden="true"></i>
|
||||
<p>${noticeMessage}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
document.querySelector( '#smush-box-bulk .wp-smush-bulk-wrapper' ).outerHTML += upsellHtml;
|
||||
}
|
||||
};
|
||||
|
||||
WP_Smush.helpers.init();
|
||||
}() );
|
@ -0,0 +1,385 @@
|
||||
/* global WP_Smush */
|
||||
|
||||
/**
|
||||
* Scan Media Library.
|
||||
*
|
||||
*/
|
||||
import SmushProgress from '../common/progressbar';
|
||||
import MediaLibraryScanner from '../common/media-library-scanner';
|
||||
import { GlobalStats } from '../common/globalStats';
|
||||
|
||||
( function() {
|
||||
'use strict';
|
||||
if ( ! window.wp_smush_msgs ) {
|
||||
return;
|
||||
}
|
||||
const $ = document.querySelector.bind( document );
|
||||
const existScanProgressBar = $( '.wp-smush-scan-progress-bar-wrapper' );
|
||||
if ( ! existScanProgressBar ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const recheckImagesBtn = $( '.wp-smush-scan' );
|
||||
if ( ! recheckImagesBtn ) {
|
||||
return;
|
||||
}
|
||||
const bulkSmushButton = $( '.wp-smush-bo-start' ) || $( '.wp-smush-bulk-wrapper .wp-smush-all' );
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
class MediaLibraryScannerOnBulkSmush extends MediaLibraryScanner {
|
||||
constructor() {
|
||||
super();
|
||||
this.runBulkSmushOnComplete = false;
|
||||
this.restoreButton = $( '.wp-smush-restore' );
|
||||
this.autoBulkSmushNotification = $( '.wp-smush-auto-bulk-smush-notification' );
|
||||
}
|
||||
|
||||
startScanThenBulkSmushOnComplete() {
|
||||
this.runBulkSmushOnComplete = true;
|
||||
return this.startScan( true );
|
||||
}
|
||||
|
||||
onStart() {
|
||||
this.hideRecheckNotice();
|
||||
this.disableRelatedButtons();
|
||||
this.setRecheckImagesButtonOnLoad();
|
||||
this.toggleBulkSmushBoxContent();
|
||||
return this;
|
||||
}
|
||||
|
||||
onStartFailure( response ) {
|
||||
super.onStartFailure( response );
|
||||
this.revertRelatedButtons();
|
||||
}
|
||||
|
||||
onCloseProgressBar() {
|
||||
this.maybeHideAutoBulkSmushNotification();
|
||||
}
|
||||
|
||||
disableRelatedButtons() {
|
||||
this.restoreButton.setAttribute( 'disabled', true );
|
||||
if ( bulkSmushButton ) {
|
||||
bulkSmushButton.setAttribute( 'disabled', true );
|
||||
this.setInnerText( bulkSmushButton, __( 'Waiting for Re-check to finish', 'wp-smushit' ) );
|
||||
}
|
||||
}
|
||||
|
||||
revertRelatedButtons() {
|
||||
if ( bulkSmushButton ) {
|
||||
bulkSmushButton.removeAttribute( 'disabled' );
|
||||
this.revertInnerText( bulkSmushButton );
|
||||
}
|
||||
this.restoreButton.removeAttribute( 'disabled' );
|
||||
this.revertRecheckImagesButton();
|
||||
return this;
|
||||
}
|
||||
|
||||
setRecheckImagesButtonOnLoad() {
|
||||
// recheckImagesBtn.classList.add( 'sui-button-onload' );
|
||||
this.disableRecheckImagesButton();
|
||||
this.setInnerText( recheckImagesBtn.querySelector( '.wp-smush-inner-text' ), __( 'Checking Images', 'wp-smushit' ) );
|
||||
}
|
||||
|
||||
disableRecheckImagesButton() {
|
||||
recheckImagesBtn.setAttribute( 'disabled', true );
|
||||
}
|
||||
|
||||
revertRecheckImagesButton() {
|
||||
// recheckImagesBtn.classList.remove( 'sui-button-onload' );
|
||||
recheckImagesBtn.removeAttribute( 'disabled' );
|
||||
this.revertInnerText( recheckImagesBtn.querySelector( '.wp-smush-inner-text' ) );
|
||||
}
|
||||
|
||||
beforeUpdateStatus( stats ) {
|
||||
this.runBulkSmushOnComplete = stats?.optimize_on_scan_completed;
|
||||
this.maybeShowAutoBulkSmushNotification();
|
||||
}
|
||||
|
||||
onDead( stats ) {
|
||||
super.onDead( stats );
|
||||
this.revertRelatedButtons();
|
||||
this.setRequiredScanForBulkSmushButton();
|
||||
}
|
||||
|
||||
onFinish( stats ) {
|
||||
const globalStats = stats.global_stats;
|
||||
super.onFinish( stats );
|
||||
this.revertRelatedButtons();
|
||||
this.toggleBulkSmushDescription( globalStats );
|
||||
if ( globalStats.is_outdated ) {
|
||||
this.setRequiredScanForBulkSmushButton();
|
||||
} else {
|
||||
this.removeScanEventFromBulkSmushButton();
|
||||
}
|
||||
|
||||
this.revertRecheckWarning();
|
||||
}
|
||||
|
||||
onCompleted( stats ) {
|
||||
const requiredReloadPage = ! bulkSmushButton;
|
||||
if ( requiredReloadPage ) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
this.onFinish( stats );
|
||||
const globalStats = stats.global_stats;
|
||||
const allImagesSmushed = globalStats.remaining_count < 1;
|
||||
if ( allImagesSmushed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! this.runBulkSmushOnComplete ) {
|
||||
this.showRecheckNoticeSuccess();
|
||||
return;
|
||||
}
|
||||
this.runBulkSmushOnComplete = false;
|
||||
|
||||
this.triggerBulkSmushEvent( stats );
|
||||
}
|
||||
|
||||
showNotice( stats ) {
|
||||
if ( ! stats.notice ) {
|
||||
return;
|
||||
}
|
||||
let type = 'success';
|
||||
if ( 'undefined' !== typeof stats.noticeType ) {
|
||||
type = stats.noticeType;
|
||||
}
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-ajax-notice',
|
||||
'<p>' + stats.notice + '</p>',
|
||||
{ type, icon: 'check-tick' }
|
||||
);
|
||||
}
|
||||
|
||||
showRecheckNoticeSuccess() {
|
||||
const recheckNotice = $( '.wp-smush-recheck-images-notice-box' );
|
||||
if ( ! recheckNotice ) {
|
||||
return;
|
||||
}
|
||||
this.showAnElement( recheckNotice );
|
||||
this.hideAnElement( recheckNotice.querySelector( '.wp-smush-recheck-images-notice-warning' ) );
|
||||
this.showAnElement( recheckNotice.querySelector( '.wp-smush-recheck-images-notice-success' ) );
|
||||
}
|
||||
|
||||
showRecheckNoticeWarning() {
|
||||
const recheckNotice = $( '.wp-smush-recheck-images-notice-box' );
|
||||
if ( ! recheckNotice ) {
|
||||
return;
|
||||
}
|
||||
this.showAnElement( recheckNotice );
|
||||
this.hideAnElement( recheckNotice.querySelector( '.wp-smush-recheck-images-notice-success' ) );
|
||||
this.showAnElement( recheckNotice.querySelector( '.wp-smush-recheck-images-notice-warning' ) );
|
||||
}
|
||||
|
||||
hideRecheckNotice() {
|
||||
this.hideAnElement( $( '.wp-smush-recheck-images-notice-box' ) );
|
||||
}
|
||||
|
||||
showProgressErrorNoticeOnRecheckNotice() {
|
||||
const recheckWarningElement = $( '.wp-smush-recheck-images-notice-box .wp-smush-recheck-images-notice-warning' );
|
||||
if ( ! recheckWarningElement ) {
|
||||
return;
|
||||
}
|
||||
recheckWarningElement.classList.add( 'sui-notice-error' );
|
||||
recheckWarningElement.classList.remove( 'sui-notice-warning' );
|
||||
this.setInnerText( recheckWarningElement.querySelector( 'span' ), this.getErrorProgressMessage() );
|
||||
this.showRecheckNoticeWarning();
|
||||
}
|
||||
|
||||
revertRecheckWarning() {
|
||||
const recheckWarningElement = $( '.wp-smush-recheck-images-notice-box .wp-smush-recheck-images-notice-warning' );
|
||||
if ( ! recheckWarningElement ) {
|
||||
return;
|
||||
}
|
||||
recheckWarningElement.classList.add( 'sui-notice-warning' );
|
||||
recheckWarningElement.classList.remove( 'sui-notice-error' );
|
||||
this.revertInnerText( recheckWarningElement.querySelector( 'span' ) );
|
||||
}
|
||||
|
||||
triggerBulkSmushEvent( stats ) {
|
||||
this.disableRecheckImagesButton();
|
||||
|
||||
if ( stats.enabled_background_process ) {
|
||||
this.triggerBackgroundBulkSmushEvent( stats.global_stats );
|
||||
} else {
|
||||
this.triggerAjaxBulkSmushEvent( stats.global_stats );
|
||||
}
|
||||
}
|
||||
|
||||
toggleBulkSmushDescription( globalStats ) {
|
||||
if ( SmushProgress.isEmptyObject ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( globalStats.remaining_count < 1 ) {
|
||||
SmushProgress.hideBulkSmushDescription();
|
||||
SmushProgress.showBulkSmushAllDone();
|
||||
} else {
|
||||
SmushProgress.showBulkSmushDescription();
|
||||
SmushProgress.hideBulkSmushAllDone();
|
||||
}
|
||||
}
|
||||
|
||||
setRequiredScanForBulkSmushButton() {
|
||||
bulkSmushButton && bulkSmushButton.classList.add( 'wp-smush-scan-and-bulk-smush' );
|
||||
}
|
||||
|
||||
removeScanEventFromBulkSmushButton() {
|
||||
bulkSmushButton && bulkSmushButton.classList.remove( 'wp-smush-scan-and-bulk-smush' );
|
||||
}
|
||||
|
||||
triggerBackgroundBulkSmushEvent( globalStats ) {
|
||||
document.dispatchEvent(
|
||||
new CustomEvent( 'backgroundBulkSmushOnScanCompleted', {
|
||||
detail: globalStats
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
triggerAjaxBulkSmushEvent( globalStats ) {
|
||||
document.dispatchEvent(
|
||||
new CustomEvent( 'ajaxBulkSmushOnScanCompleted', {
|
||||
detail: globalStats
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
onCancelled( stats ) {
|
||||
this.onFinish( stats );
|
||||
this.runBulkSmushOnComplete = false;
|
||||
this.setRequiredScanForBulkSmushButton();
|
||||
}
|
||||
|
||||
maybeShowAutoBulkSmushNotification() {
|
||||
if (
|
||||
! this.runBulkSmushOnComplete
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.showAnElement( this.autoBulkSmushNotification );
|
||||
}
|
||||
|
||||
maybeHideAutoBulkSmushNotification() {
|
||||
if (
|
||||
! this.runBulkSmushOnComplete
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.hideAnElement( this.autoBulkSmushNotification );
|
||||
}
|
||||
|
||||
toggleBulkSmushBoxContent() {
|
||||
GlobalStats.resetAndHideBulkErrors();
|
||||
this.toggleBulkSmushDescription( GlobalStats.getGlobalStats() );
|
||||
}
|
||||
}
|
||||
const mediaLibScanner = new MediaLibraryScannerOnBulkSmush();
|
||||
|
||||
/**
|
||||
* Event Listeners.
|
||||
*/
|
||||
|
||||
// Background Scan Media Library.
|
||||
const registerScanMediaLibraryEvent = () => {
|
||||
if ( ! recheckImagesBtn ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const canScanInBackground = recheckImagesBtn.classList.contains( 'wp-smush-background-scan' );
|
||||
if ( ! canScanInBackground ) {
|
||||
return;
|
||||
}
|
||||
|
||||
recheckImagesBtn.addEventListener( 'click', () => mediaLibScanner.startScan() );
|
||||
|
||||
//Check scan is running.
|
||||
if ( window.wp_smushit_data.media_library_scan?.in_processing ) {
|
||||
mediaLibScanner.onStart().showProgressBar().autoSyncStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( window.location.search.includes( 'smush-action=start-scan-media' ) ) {
|
||||
recheckImagesBtn.click();
|
||||
const removeScanActionFromURLAddress = () => {
|
||||
const cleanedURL = window.location.href.replace( '&smush-action=start-scan-media', '' );
|
||||
window.history.pushState( null, null, cleanedURL );
|
||||
};
|
||||
removeScanActionFromURLAddress();
|
||||
}
|
||||
};
|
||||
registerScanMediaLibraryEvent();
|
||||
|
||||
/**
|
||||
* Recheck Images Notice events.
|
||||
*/
|
||||
const registerEventsRelatedRecheckImagesNotice = () => {
|
||||
const recheckImagesNotice = $( '.wp-smush-recheck-images-notice-box' );
|
||||
if ( ! recheckImagesNotice || ! recheckImagesBtn ) {
|
||||
return;
|
||||
}
|
||||
const triggerBackgroundScanImagesLink = recheckImagesNotice.querySelector( '.wp-smush-trigger-background-scan' );
|
||||
if ( triggerBackgroundScanImagesLink ) {
|
||||
triggerBackgroundScanImagesLink.onclick = ( e ) => {
|
||||
e.preventDefault();
|
||||
recheckImagesBtn.click();
|
||||
};
|
||||
|
||||
if ( window.wp_smushit_data.media_library_scan?.is_dead ) {
|
||||
mediaLibScanner.showProgressErrorNoticeOnRecheckNotice();
|
||||
} else if( window.wp_smushit_data.is_outdated ) {
|
||||
mediaLibScanner.showRecheckNoticeWarning();
|
||||
}
|
||||
}
|
||||
const triggerBulkSmush = recheckImagesNotice.querySelector( '.wp-smush-trigger-bulk-smush' );
|
||||
if ( triggerBulkSmush && bulkSmushButton ) {
|
||||
triggerBulkSmush.onclick = ( e ) => {
|
||||
e.preventDefault();
|
||||
recheckImagesNotice.classList.add( 'sui-hidden' );
|
||||
bulkSmushButton.click();
|
||||
};
|
||||
}
|
||||
const dismissNotices = recheckImagesNotice.querySelectorAll( 'button.sui-button-icon' );
|
||||
if ( dismissNotices ) {
|
||||
dismissNotices.forEach( ( dismissNotice ) => {
|
||||
dismissNotice.onclick = ( e ) => {
|
||||
dismissNotice.closest( '.sui-recheck-images-notice' ).classList.add( 'sui-hidden' );
|
||||
};
|
||||
} );
|
||||
}
|
||||
|
||||
document.addEventListener( 'onSavedSmushSettings', function( e ) {
|
||||
if ( ! e?.detail?.is_outdated_stats ) {
|
||||
return;
|
||||
}
|
||||
|
||||
mediaLibScanner.setRequiredScanForBulkSmushButton();
|
||||
|
||||
recheckImagesNotice.classList.remove( 'sui-hidden' );
|
||||
recheckImagesNotice.querySelector( '.wp-smush-recheck-images-notice-success' ).classList.add( 'sui-hidden' );
|
||||
recheckImagesNotice.querySelector( '.wp-smush-recheck-images-notice-warning' ).classList.remove( 'sui-hidden' );
|
||||
} );
|
||||
};
|
||||
|
||||
registerEventsRelatedRecheckImagesNotice();
|
||||
|
||||
// Scan and Bulk Smush.
|
||||
const registerScanAndBulkSmushEvent = () => {
|
||||
if ( ! bulkSmushButton ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleScanAndBulkSmush = ( e ) => {
|
||||
const shouldRunScan = bulkSmushButton.classList.contains( 'wp-smush-scan-and-bulk-smush' );
|
||||
if ( ! shouldRunScan ) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
mediaLibScanner.startScanThenBulkSmushOnComplete();
|
||||
};
|
||||
|
||||
bulkSmushButton.addEventListener( 'click', handleScanAndBulkSmush );
|
||||
};
|
||||
registerScanAndBulkSmushEvent();
|
||||
}() );
|
@ -0,0 +1,63 @@
|
||||
/* global WP_Smush */
|
||||
|
||||
/**
|
||||
* Scan Media Library.
|
||||
*
|
||||
*/
|
||||
import MediaLibraryScanner from '../common/media-library-scanner';
|
||||
|
||||
( function() {
|
||||
'use strict';
|
||||
if ( ! window.wp_smush_msgs ) {
|
||||
return;
|
||||
}
|
||||
const $ = document.querySelector.bind( document );
|
||||
const existScanProgressBar = $( '.wp-smush-scan-progress-bar-wrapper' );
|
||||
if ( ! existScanProgressBar ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const recheckImagesBtn = $( '.wp-smush-scan' );
|
||||
if ( recheckImagesBtn ) {
|
||||
return;
|
||||
}
|
||||
//Check scan is running.
|
||||
const is_scan_running = window.wp_smushit_data.media_library_scan?.in_processing;
|
||||
if ( ! is_scan_running ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
class mediaLibraryScannerOnDashboard extends MediaLibraryScanner {
|
||||
constructor() {
|
||||
super();
|
||||
this.bulkSmushLink = $( '.wp-smush-bulk-smush-link' );
|
||||
}
|
||||
onShowProgressBar() {
|
||||
this.disableBulkSmushLink();
|
||||
}
|
||||
|
||||
onCloseProgressBar() {
|
||||
this.revertBulkSmushLink();
|
||||
}
|
||||
|
||||
disableBulkSmushLink() {
|
||||
if ( ! this.bulkSmushLink ) {
|
||||
return;
|
||||
}
|
||||
this.bulkSmushLink.setAttribute( 'disabled', true );
|
||||
this.setInnerText( this.bulkSmushLink, __( 'Waiting for Re-check to finish', 'wp-smushit' ) );
|
||||
}
|
||||
|
||||
revertBulkSmushLink() {
|
||||
if ( ! this.bulkSmushLink ) {
|
||||
return;
|
||||
}
|
||||
this.bulkSmushLink.removeAttribute( 'disabled' );
|
||||
this.revertInnerText( this.bulkSmushLink );
|
||||
}
|
||||
}
|
||||
|
||||
( new mediaLibraryScannerOnDashboard() ).showProgressBar().autoSyncStatus();
|
||||
}() );
|
@ -0,0 +1,52 @@
|
||||
import Smush from '../smush/smush';
|
||||
import SmushProcess from '../common/progressbar';
|
||||
|
||||
(function($) {
|
||||
$(function() {
|
||||
/** Handle NextGen Gallery smush button click **/
|
||||
$('body').on('click', '.wp-smush-nextgen-send', function (e) {
|
||||
// prevent the default action
|
||||
e.preventDefault();
|
||||
new Smush($(this), false, 'nextgen');
|
||||
});
|
||||
|
||||
/** Handle NextGen Gallery Bulk smush button click **/
|
||||
$('body').on('click', '.wp-smush-nextgen-bulk', function (e) {
|
||||
// prevent the default action
|
||||
e.preventDefault();
|
||||
|
||||
// Remove existing Re-Smush notices.
|
||||
// TODO: REMOVE re-smush-notice since no longer used.
|
||||
$('.wp-smush-resmush-notice').remove();
|
||||
|
||||
//Check for ids, if there is none (Unsmushed or lossless), don't call smush function
|
||||
if (
|
||||
'undefined' === typeof wp_smushit_data ||
|
||||
(wp_smushit_data.unsmushed.length === 0 &&
|
||||
wp_smushit_data.resmush.length === 0)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bulkSmush = new Smush( $(this), true, 'nextgen' );
|
||||
SmushProcess.setOnCancelCallback( () => {
|
||||
bulkSmush.cancelAjax();
|
||||
}).update( 0, bulkSmush.ids.length ).show();
|
||||
|
||||
jQuery('.wp-smush-all, .wp-smush-scan').prop('disabled', true);
|
||||
$('.wp-smush-notice.wp-smush-remaining').hide();
|
||||
|
||||
// Run bulk Smush.
|
||||
bulkSmush.run();
|
||||
})
|
||||
.on('click', '.wp-smush-trigger-nextgen-bulk', function(e){
|
||||
e.preventDefault();
|
||||
const bulkSmushButton = $('.wp-smush-nextgen-bulk');
|
||||
if ( bulkSmushButton.length ) {
|
||||
bulkSmushButton.trigger('click');
|
||||
SUI.closeNotice( 'wp-smush-ajax-notice' );
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}(window.jQuery));
|
81
wp-content/plugins/wp-smushit/_src/js/modules/notice.js
Normal file
81
wp-content/plugins/wp-smushit/_src/js/modules/notice.js
Normal file
@ -0,0 +1,81 @@
|
||||
/* global ajaxurl */
|
||||
/* global wp_smush_msgs */
|
||||
|
||||
( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
const s3alert = $( '#wp-smush-s3support-alert' );
|
||||
|
||||
/**
|
||||
* S3 support alert.
|
||||
*
|
||||
* @since 3.6.2 Moved from class-s3.php
|
||||
*/
|
||||
if ( s3alert.length ) {
|
||||
const noticeOptions = {
|
||||
type: 'warning',
|
||||
icon: 'info',
|
||||
dismiss: {
|
||||
show: true,
|
||||
label: wp_smush_msgs.noticeDismiss,
|
||||
tooltip: wp_smush_msgs.noticeDismissTooltip,
|
||||
},
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-s3support-alert',
|
||||
s3alert.data( 'message' ),
|
||||
noticeOptions
|
||||
);
|
||||
}
|
||||
|
||||
// Dismiss S3 support alert.
|
||||
s3alert.on( 'click', 'button', () => {
|
||||
$.post( ajaxurl,
|
||||
{
|
||||
action: 'dismiss_s3support_alert',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce,
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
// Remove API message.
|
||||
$( '#wp-smush-api-message button.sui-button-icon' ).on( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
const notice = $( '#wp-smush-api-message' );
|
||||
notice.slideUp( 'slow', function() {
|
||||
notice.remove();
|
||||
} );
|
||||
$.post( ajaxurl,
|
||||
{
|
||||
action: 'hide_api_message',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce,
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
// Hide the notice after a CTA button was clicked
|
||||
function removeNotice( e ) {
|
||||
const $notice = $( e.currentTarget ).closest( '.smush-notice' );
|
||||
$notice.fadeTo( 100, 0, () =>
|
||||
$notice.slideUp( 100, () => $notice.remove() )
|
||||
);
|
||||
}
|
||||
|
||||
// Only used for the Dashboard notification for now.
|
||||
$( '.smush-notice .smush-notice-act' ).on( 'click', ( e ) => {
|
||||
removeNotice( e );
|
||||
} );
|
||||
|
||||
// Dismiss the update notice.
|
||||
$( '.wp-smush-update-info' ).on( 'click', '.notice-dismiss', ( e ) => {
|
||||
e.preventDefault();
|
||||
removeNotice( e );
|
||||
$.post( ajaxurl,
|
||||
{
|
||||
action: 'dismiss_update_info',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce,
|
||||
}
|
||||
);
|
||||
} );
|
||||
}( jQuery ) );
|
378
wp-content/plugins/wp-smushit/_src/js/modules/onboarding.js
Normal file
378
wp-content/plugins/wp-smushit/_src/js/modules/onboarding.js
Normal file
@ -0,0 +1,378 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Modals JavaScript code.
|
||||
*/
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Onboarding modal.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
WP_Smush.onboarding = {
|
||||
membership: 'free', // Assume free by default.
|
||||
onboardingModal: document.getElementById( 'smush-onboarding-dialog' ),
|
||||
first_slide: 'usage',
|
||||
settings: {
|
||||
first: true,
|
||||
last: false,
|
||||
slide: 'usage',
|
||||
value: false,
|
||||
},
|
||||
selection: {
|
||||
usage: false,
|
||||
auto: true,
|
||||
lossy: true,
|
||||
strip_exif: true,
|
||||
original: false,
|
||||
lazy_load: true,
|
||||
},
|
||||
contentContainer: document.getElementById( 'smush-onboarding-content' ),
|
||||
onboardingSlides: [
|
||||
'usage',
|
||||
'auto',
|
||||
'lossy',
|
||||
'strip_exif',
|
||||
'original',
|
||||
'lazy_load',
|
||||
],
|
||||
touchX: null,
|
||||
touchY: null,
|
||||
recheckImagesLink: '',
|
||||
/**
|
||||
* Init module.
|
||||
*/
|
||||
init() {
|
||||
if ( ! this.onboardingModal ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dialog = document.getElementById( 'smush-onboarding' );
|
||||
|
||||
this.membership = dialog.dataset.type;
|
||||
this.recheckImagesLink = dialog.dataset.ctaUrl;
|
||||
|
||||
if ( 'pro' !== this.membership ) {
|
||||
this.onboardingSlides = [
|
||||
'usage',
|
||||
'auto',
|
||||
'lossy',
|
||||
'strip_exif',
|
||||
'lazy_load',
|
||||
];
|
||||
}
|
||||
|
||||
if ( 'false' === dialog.dataset.tracking ) {
|
||||
this.onboardingSlides.pop();
|
||||
}
|
||||
|
||||
this.renderTemplate();
|
||||
|
||||
// Skip setup.
|
||||
const skipButton = this.onboardingModal.querySelector(
|
||||
'.smush-onboarding-skip-link'
|
||||
);
|
||||
if ( skipButton ) {
|
||||
skipButton.addEventListener( 'click', this.skipSetup.bind( this ) );
|
||||
}
|
||||
|
||||
// Show the modal.
|
||||
window.SUI.openModal(
|
||||
'smush-onboarding-dialog',
|
||||
'wpcontent',
|
||||
undefined,
|
||||
false
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get swipe coordinates.
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
handleTouchStart( e ) {
|
||||
const firstTouch = e.touches[ 0 ];
|
||||
this.touchX = firstTouch.clientX;
|
||||
this.touchY = firstTouch.clientY;
|
||||
},
|
||||
|
||||
/**
|
||||
* Process swipe left/right.
|
||||
*
|
||||
* @param {Object} e
|
||||
*/
|
||||
handleTouchMove( e ) {
|
||||
if ( ! this.touchX || ! this.touchY ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const xUp = e.touches[ 0 ].clientX,
|
||||
yUp = e.touches[ 0 ].clientY,
|
||||
xDiff = this.touchX - xUp,
|
||||
yDiff = this.touchY - yUp;
|
||||
|
||||
if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {
|
||||
if ( xDiff > 0 ) {
|
||||
if ( false === WP_Smush.onboarding.settings.last ) {
|
||||
WP_Smush.onboarding.next( null, 'next' );
|
||||
}
|
||||
} else if ( false === WP_Smush.onboarding.settings.first ) {
|
||||
WP_Smush.onboarding.next( null, 'prev' );
|
||||
}
|
||||
}
|
||||
|
||||
this.touchX = null;
|
||||
this.touchY = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the template, register new listeners.
|
||||
*
|
||||
* @param {string} directionClass Accepts: fadeInRight, fadeInLeft, none.
|
||||
*/
|
||||
renderTemplate( directionClass = 'none' ) {
|
||||
// Grab the selected value.
|
||||
const input = this.onboardingModal.querySelector(
|
||||
'input[type="checkbox"]'
|
||||
);
|
||||
if ( input ) {
|
||||
this.selection[ input.id ] = input.checked;
|
||||
}
|
||||
|
||||
const template = WP_Smush.onboarding.template( 'smush-onboarding' );
|
||||
const content = template( this.settings );
|
||||
|
||||
if ( content ) {
|
||||
this.contentContainer.innerHTML = content;
|
||||
|
||||
if ( 'none' === directionClass ) {
|
||||
this.contentContainer.classList.add( 'loaded' );
|
||||
} else {
|
||||
this.contentContainer.classList.remove( 'loaded' );
|
||||
this.contentContainer.classList.add( directionClass );
|
||||
setTimeout( () => {
|
||||
this.contentContainer.classList.add( 'loaded' );
|
||||
this.contentContainer.classList.remove(
|
||||
directionClass
|
||||
);
|
||||
}, 600 );
|
||||
}
|
||||
}
|
||||
|
||||
this.onboardingModal.addEventListener(
|
||||
'touchstart',
|
||||
this.handleTouchStart,
|
||||
false
|
||||
);
|
||||
this.onboardingModal.addEventListener(
|
||||
'touchmove',
|
||||
this.handleTouchMove,
|
||||
false
|
||||
);
|
||||
|
||||
this.bindSubmit();
|
||||
},
|
||||
|
||||
/**
|
||||
* Catch "Finish setup wizard" button click.
|
||||
*/
|
||||
bindSubmit() {
|
||||
const submitButton = this.onboardingModal.querySelector(
|
||||
'button[type="submit"]'
|
||||
);
|
||||
const self = this;
|
||||
|
||||
if ( submitButton ) {
|
||||
submitButton.addEventListener( 'click', function( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
// Because we are not rendering the template, we need to update the last element value.
|
||||
const input = self.onboardingModal.querySelector(
|
||||
'input[type="checkbox"]'
|
||||
);
|
||||
if ( input ) {
|
||||
self.selection[ input.id ] = input.checked;
|
||||
}
|
||||
|
||||
const _nonce = document.getElementById(
|
||||
'smush_quick_setup_nonce'
|
||||
);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=smush_setup', true );
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
self.onFinishingSetup();
|
||||
} else {
|
||||
window.console.log(
|
||||
'Request failed. Returned status of ' +
|
||||
xhr.status
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send(
|
||||
'smush_settings=' +
|
||||
JSON.stringify( self.selection ) +
|
||||
'&_ajax_nonce=' +
|
||||
_nonce.value
|
||||
);
|
||||
} );
|
||||
}
|
||||
},
|
||||
|
||||
onFinishingSetup() {
|
||||
this.onFinish();
|
||||
this.startRecheckImages();
|
||||
},
|
||||
|
||||
onFinish() {
|
||||
window.SUI.closeModal();
|
||||
},
|
||||
|
||||
startRecheckImages() {
|
||||
if ( ! this.recheckImagesLink ) {
|
||||
return;
|
||||
}
|
||||
window.location.href = this.recheckImagesLink;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle navigation.
|
||||
*
|
||||
* @param {Object} e
|
||||
* @param {null|string} whereTo
|
||||
*/
|
||||
next( e, whereTo = null ) {
|
||||
const index = this.onboardingSlides.indexOf( this.settings.slide );
|
||||
let newIndex = 0;
|
||||
|
||||
if ( ! whereTo ) {
|
||||
newIndex =
|
||||
null !== e && e.classList.contains( 'next' )
|
||||
? index + 1
|
||||
: index - 1;
|
||||
} else {
|
||||
newIndex = 'next' === whereTo ? index + 1 : index - 1;
|
||||
}
|
||||
|
||||
const directionClass =
|
||||
null !== e && e.classList.contains( 'next' )
|
||||
? 'fadeInRight'
|
||||
: 'fadeInLeft';
|
||||
|
||||
this.settings = {
|
||||
first: 0 === newIndex,
|
||||
last: newIndex + 1 === this.onboardingSlides.length, // length !== index
|
||||
slide: this.onboardingSlides[ newIndex ],
|
||||
value: this.selection[ this.onboardingSlides[ newIndex ] ],
|
||||
};
|
||||
|
||||
this.renderTemplate( directionClass );
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle circle navigation.
|
||||
*
|
||||
* @param {string} target
|
||||
*/
|
||||
goTo( target ) {
|
||||
const newIndex = this.onboardingSlides.indexOf( target );
|
||||
|
||||
this.settings = {
|
||||
first: 0 === newIndex,
|
||||
last: newIndex + 1 === this.onboardingSlides.length, // length !== index
|
||||
slide: target,
|
||||
value: this.selection[ target ],
|
||||
};
|
||||
|
||||
this.renderTemplate();
|
||||
},
|
||||
|
||||
/**
|
||||
* Skip onboarding experience.
|
||||
*/
|
||||
skipSetup() {
|
||||
const _nonce = document.getElementById( 'smush_quick_setup_nonce' );
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(
|
||||
'POST',
|
||||
ajaxurl + '?action=skip_smush_setup&_ajax_nonce=' + _nonce.value
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
this.onSkipSetup();
|
||||
} else {
|
||||
window.console.log(
|
||||
'Request failed. Returned status of ' + xhr.status
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
onSkipSetup() {
|
||||
this.onFinish();
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide new features modal.
|
||||
* @since 3.7.0
|
||||
* @since 3.12.2 Add a new parameter redirectUrl
|
||||
*/
|
||||
hideUpgradeModal: ( e, button ) => {
|
||||
e.preventDefault();
|
||||
button.classList.add( 'wp-smush-link-in-progress' );
|
||||
const redirectUrl = button?.href;
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=hide_new_features&_ajax_nonce=' + window.wp_smush_msgs.nonce );
|
||||
xhr.onload = () => {
|
||||
window.SUI.closeModal();
|
||||
button.classList.remove( 'wp-smush-link-in-progress' );
|
||||
if ( 200 === xhr.status ) {
|
||||
if ( redirectUrl ) {
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
} else {
|
||||
window.console.log(
|
||||
'Request failed. Returned status of ' + xhr.status
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Template function (underscores based).
|
||||
*
|
||||
* @type {Function}
|
||||
*/
|
||||
WP_Smush.onboarding.template = _.memoize( ( id ) => {
|
||||
let compiled;
|
||||
const options = {
|
||||
evaluate: /<#([\s\S]+?)#>/g,
|
||||
interpolate: /{{{([\s\S]+?)}}}/g,
|
||||
escape: /{{([^}]+?)}}(?!})/g,
|
||||
variable: 'data',
|
||||
};
|
||||
|
||||
return ( data ) => {
|
||||
_.templateSettings = options;
|
||||
compiled =
|
||||
compiled ||
|
||||
_.template( document.getElementById( id ).innerHTML );
|
||||
data.first_slide = WP_Smush.onboarding.first_slide;
|
||||
return compiled( data );
|
||||
};
|
||||
} );
|
||||
|
||||
window.addEventListener( 'load', () => WP_Smush.onboarding.init() );
|
||||
}() );
|
13
wp-content/plugins/wp-smushit/_src/js/shared-ui.js
Normal file
13
wp-content/plugins/wp-smushit/_src/js/shared-ui.js
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Shared UI JS libraries. Use only what we need to keep the vendor file size smaller.
|
||||
*
|
||||
* @package
|
||||
*/
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/code-snippet' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/modal-dialog' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/notifications' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/select2.full' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/select2' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/tabs' );
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/upload' ); // Used on lazy load page (since 3.2.2).
|
||||
require( '@wpmudev/shared-ui/dist/js/_src/reviews' );
|
147
wp-content/plugins/wp-smushit/_src/js/smush/blocks.js
Normal file
147
wp-content/plugins/wp-smushit/_src/js/smush/blocks.js
Normal file
@ -0,0 +1,147 @@
|
||||
/**
|
||||
* BLOCK: extend image block
|
||||
*/
|
||||
const { createHigherOrderComponent } = wp.compose,
|
||||
{ Fragment } = wp.element,
|
||||
{ InspectorControls } = wp.blockEditor,
|
||||
{ PanelBody } = wp.components;
|
||||
|
||||
/**
|
||||
* Transform bytes to human readable format.
|
||||
*
|
||||
* @param {number} bytes
|
||||
* @return {string} Readable size string.
|
||||
*/
|
||||
function humanFileSize( bytes ) {
|
||||
const thresh = 1024,
|
||||
units = [ 'kB', 'MB', 'GB', 'TB' ];
|
||||
|
||||
if ( Math.abs( bytes ) < thresh ) {
|
||||
return bytes + ' B';
|
||||
}
|
||||
|
||||
let u = -1;
|
||||
do {
|
||||
bytes /= thresh;
|
||||
++u;
|
||||
} while ( Math.abs( bytes ) >= thresh && u < units.length - 1 );
|
||||
|
||||
return bytes.toFixed( 1 ) + ' ' + units[ u ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Smush stats table.
|
||||
*
|
||||
* @param {number} id
|
||||
* @param {Object} stats
|
||||
* @return {*} Smush stats.
|
||||
*/
|
||||
export function smushStats( id, stats ) {
|
||||
if ( 'undefined' === typeof stats ) {
|
||||
return window.smush_vars.strings.gb.select_image;
|
||||
} else if ( 'string' === typeof stats ) {
|
||||
return stats;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
id="smush-stats"
|
||||
className="sui-smush-media smush-stats-wrapper hidden"
|
||||
style={ { display: 'block' } }
|
||||
>
|
||||
<table className="wp-smush-stats-holder">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="smush-stats-header">
|
||||
{ window.smush_vars.strings.gb.size }
|
||||
</th>
|
||||
<th className="smush-stats-header">
|
||||
{ window.smush_vars.strings.gb.savings }
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{ Object.keys( stats.sizes )
|
||||
.filter( ( item ) => 0 < stats.sizes[ item ].percent )
|
||||
.map( ( item, i ) => (
|
||||
<tr key={ i }>
|
||||
<td>{ item.toUpperCase() }</td>
|
||||
<td>
|
||||
{ humanFileSize(
|
||||
stats.sizes[ item ].bytes
|
||||
) }{ ' ' }
|
||||
( { stats.sizes[ item ].percent }% )
|
||||
</td>
|
||||
</tr>
|
||||
) ) }
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch image data. If image is Smushing, update in 3 seconds.
|
||||
*
|
||||
* TODO: this could be optimized not to query so much.
|
||||
*
|
||||
* @param {Object} props
|
||||
*/
|
||||
export function fetchProps( props ) {
|
||||
const image = new wp.api.models.Media( { id: props.attributes.id } ),
|
||||
smushData = props.attributes.smush;
|
||||
|
||||
image.fetch( { attribute: 'smush' } ).done( function( img ) {
|
||||
if ( 'string' === typeof img.smush ) {
|
||||
props.setAttributes( { smush: img.smush } );
|
||||
//setTimeout( () => fetch( props ), 3000 );
|
||||
} else if (
|
||||
'undefined' !== typeof img.smush &&
|
||||
( 'undefined' === typeof smushData ||
|
||||
JSON.stringify( smushData ) !== JSON.stringify( img.smush ) )
|
||||
) {
|
||||
props.setAttributes( { smush: img.smush } );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the block’s edit component.
|
||||
* Receives the original block BlockEdit component and returns a new wrapped component.
|
||||
*/
|
||||
const smushStatsControl = createHigherOrderComponent( ( BlockEdit ) => {
|
||||
return ( props ) => {
|
||||
// If not image block or not selected, return unmodified block.
|
||||
if (
|
||||
'core/image' !== props.name ||
|
||||
! props.isSelected ||
|
||||
'undefined' === typeof props.attributes.id
|
||||
) {
|
||||
return (
|
||||
<Fragment>
|
||||
<BlockEdit { ...props } />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
const smushData = props.attributes.smush;
|
||||
fetchProps( props );
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<BlockEdit { ...props } />
|
||||
<InspectorControls>
|
||||
<PanelBody title={ window.smush_vars.strings.gb.stats }>
|
||||
{ smushStats( props.attributes.id, smushData ) }
|
||||
</PanelBody>
|
||||
</InspectorControls>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
}, 'withInspectorControl' );
|
||||
|
||||
wp.hooks.addFilter(
|
||||
'editor.BlockEdit',
|
||||
'wp-smush/smush-data-control',
|
||||
smushStatsControl
|
||||
);
|
138
wp-content/plugins/wp-smushit/_src/js/smush/cdn.js
Normal file
138
wp-content/plugins/wp-smushit/_src/js/smush/cdn.js
Normal file
@ -0,0 +1,138 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* CDN functionality.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.CDN = {
|
||||
cdnEnableButton: document.getElementById( 'smush-enable-cdn' ),
|
||||
cdnDisableButton: document.getElementById( 'smush-cancel-cdn' ),
|
||||
cdnStatsBox: document.querySelector( '.smush-cdn-stats' ),
|
||||
|
||||
init() {
|
||||
/**
|
||||
* Handle "Get Started" button click on disabled CDN page.
|
||||
*/
|
||||
if ( this.cdnEnableButton ) {
|
||||
this.cdnEnableButton.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
e.currentTarget.classList.add( 'sui-button-onload' );
|
||||
this.toggle_cdn( true );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "Deactivate' button click on CDN page.
|
||||
*/
|
||||
if ( this.cdnDisableButton ) {
|
||||
this.cdnDisableButton.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
e.currentTarget.classList.add( 'sui-button-onload' );
|
||||
|
||||
this.toggle_cdn( false );
|
||||
} );
|
||||
}
|
||||
|
||||
this.updateStatsBox();
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle CDN.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param {boolean} enable
|
||||
*/
|
||||
toggle_cdn( enable ) {
|
||||
const nonceField = document.getElementsByName(
|
||||
'wp_smush_options_nonce'
|
||||
);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=smush_toggle_cdn', true );
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
const res = JSON.parse( xhr.response );
|
||||
if ( 'undefined' !== typeof res.success && res.success ) {
|
||||
window.location.search = 'page=smush-cdn';
|
||||
} else if ( 'undefined' !== typeof res.data.message ) {
|
||||
WP_Smush.helpers.showErrorNotice( res.data.message );
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status );
|
||||
}
|
||||
};
|
||||
xhr.send(
|
||||
'param=' + enable + '&_ajax_nonce=' + nonceField[ 0 ].value
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the CDN stats box in summary meta box. Only fetch new data when on CDN page.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
updateStatsBox() {
|
||||
if (
|
||||
'undefined' === typeof this.cdnStatsBox ||
|
||||
! this.cdnStatsBox
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only fetch the new stats, when user is on CDN page.
|
||||
if ( ! window.location.search.includes( 'page=smush-cdn' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.toggleElements();
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=get_cdn_stats', true );
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
const res = JSON.parse( xhr.response );
|
||||
if ( 'undefined' !== typeof res.success && res.success ) {
|
||||
this.toggleElements();
|
||||
} else if ( 'undefined' !== typeof res.data.message ) {
|
||||
WP_Smush.helpers.showErrorNotice( res.data.message );
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status );
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
/**
|
||||
* Show/hide elements during status update in the updateStatsBox()
|
||||
*
|
||||
* @since 3.1 Moved out from updateStatsBox()
|
||||
*/
|
||||
toggleElements() {
|
||||
const spinner = this.cdnStatsBox.querySelector(
|
||||
'.sui-icon-loader'
|
||||
);
|
||||
const elements = this.cdnStatsBox.querySelectorAll(
|
||||
'.wp-smush-stats > :not(.sui-icon-loader)'
|
||||
);
|
||||
|
||||
for ( let i = 0; i < elements.length; i++ ) {
|
||||
elements[ i ].classList.toggle( 'sui-hidden' );
|
||||
}
|
||||
|
||||
spinner.classList.toggle( 'sui-hidden' );
|
||||
},
|
||||
};
|
||||
|
||||
WP_Smush.CDN.init();
|
||||
} )();
|
208
wp-content/plugins/wp-smushit/_src/js/smush/directory-scanner.js
Normal file
208
wp-content/plugins/wp-smushit/_src/js/smush/directory-scanner.js
Normal file
@ -0,0 +1,208 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Directory scanner module that will Smush images in the Directory Smush modal.
|
||||
*
|
||||
* @since 2.8.1
|
||||
*
|
||||
* @param {string|number} totalSteps
|
||||
* @param {string|number} currentStep
|
||||
* @return {Object} Scan object.
|
||||
* @class
|
||||
*/
|
||||
const DirectoryScanner = ( totalSteps, currentStep ) => {
|
||||
totalSteps = parseInt( totalSteps );
|
||||
currentStep = parseInt( currentStep );
|
||||
|
||||
let cancelling = false,
|
||||
failedItems = 0,
|
||||
skippedItems = 0;
|
||||
|
||||
const obj = {
|
||||
scan() {
|
||||
const remainingSteps = totalSteps - currentStep;
|
||||
if ( currentStep !== 0 ) {
|
||||
// Scan started on a previous page load.
|
||||
step( remainingSteps ).fail( this.showScanError );
|
||||
} else {
|
||||
jQuery
|
||||
.post( ajaxurl, {
|
||||
action: 'directory_smush_start',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce
|
||||
}, () =>
|
||||
step( remainingSteps ).fail( this.showScanError )
|
||||
)
|
||||
.fail( this.showScanError );
|
||||
}
|
||||
},
|
||||
|
||||
cancel() {
|
||||
cancelling = true;
|
||||
return jQuery.post( ajaxurl, {
|
||||
action: 'directory_smush_cancel',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce
|
||||
} );
|
||||
},
|
||||
|
||||
getProgress() {
|
||||
if ( cancelling ) {
|
||||
return 0;
|
||||
}
|
||||
// O M G ... Logic at it's finest!
|
||||
const remainingSteps = totalSteps - currentStep;
|
||||
return Math.min(
|
||||
Math.round(
|
||||
( parseInt( totalSteps - remainingSteps ) * 100 ) /
|
||||
totalSteps
|
||||
),
|
||||
99
|
||||
);
|
||||
},
|
||||
|
||||
onFinishStep( progress ) {
|
||||
jQuery( '.wp-smush-progress-dialog .sui-progress-state-text' ).html(
|
||||
currentStep -
|
||||
failedItems +
|
||||
'/' +
|
||||
totalSteps +
|
||||
' ' +
|
||||
window.wp_smush_msgs.progress_smushed
|
||||
);
|
||||
WP_Smush.directory.updateProgressBar( progress );
|
||||
},
|
||||
|
||||
onFinish() {
|
||||
WP_Smush.directory.updateProgressBar( 100 );
|
||||
window.location.href =
|
||||
window.wp_smush_msgs.directory_url + '&scan=done';
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays an error when the scan request fails.
|
||||
*
|
||||
* @param {Object} res XHR object.
|
||||
*/
|
||||
showScanError( res ) {
|
||||
const dialog = jQuery( '#wp-smush-progress-dialog' );
|
||||
|
||||
// Add the error class to show/hide elements in the dialog.
|
||||
dialog
|
||||
.removeClass( 'wp-smush-exceed-limit' )
|
||||
.addClass( 'wp-smush-scan-error' );
|
||||
|
||||
// Add the error status and description to the error message.
|
||||
dialog
|
||||
.find( '#smush-scan-error' )
|
||||
.text( `${ res.status } ${ res.statusText }` );
|
||||
|
||||
// Show/hide the 403 error specific instructions.
|
||||
const forbiddenMessage = dialog.find( '.smush-403-error-message' );
|
||||
if ( 403 !== res.status ) {
|
||||
forbiddenMessage.addClass( 'sui-hidden' );
|
||||
} else {
|
||||
forbiddenMessage.removeClass( 'sui-hidden' );
|
||||
}
|
||||
},
|
||||
|
||||
limitReached() {
|
||||
const dialog = jQuery( '#wp-smush-progress-dialog' );
|
||||
|
||||
dialog.addClass( 'wp-smush-exceed-limit' );
|
||||
dialog
|
||||
.find( '#cancel-directory-smush' )
|
||||
.attr( 'data-tooltip', window.wp_smush_msgs.bulk_resume );
|
||||
dialog
|
||||
.find( '.sui-box-body .sui-icon-close' )
|
||||
.removeClass( 'sui-icon-close' )
|
||||
.addClass( 'sui-icon-play' );
|
||||
dialog
|
||||
.find( '#cancel-directory-smush' )
|
||||
.attr( 'id', 'cancel-directory-smush-disabled' );
|
||||
},
|
||||
|
||||
resume() {
|
||||
const dialog = jQuery( '#wp-smush-progress-dialog' );
|
||||
const resume = dialog.find( '#cancel-directory-smush-disabled' );
|
||||
|
||||
dialog.removeClass( 'wp-smush-exceed-limit' );
|
||||
dialog
|
||||
.find( '.sui-box-body .sui-icon-play' )
|
||||
.removeClass( 'sui-icon-play' )
|
||||
.addClass( 'sui-icon-close' );
|
||||
resume.attr( 'data-tooltip', 'Cancel' );
|
||||
resume.attr( 'id', 'cancel-directory-smush' );
|
||||
|
||||
obj.scan();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a scan step recursively
|
||||
*
|
||||
* Private to avoid overriding
|
||||
*
|
||||
* @param {number} remainingSteps
|
||||
*/
|
||||
const step = function( remainingSteps ) {
|
||||
if ( remainingSteps >= 0 ) {
|
||||
currentStep = totalSteps - remainingSteps;
|
||||
return jQuery.post(
|
||||
ajaxurl,
|
||||
{
|
||||
action: 'directory_smush_check_step',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce,
|
||||
step: currentStep,
|
||||
},
|
||||
( response ) => {
|
||||
// We're good - continue on.
|
||||
if (
|
||||
'undefined' !== typeof response.success &&
|
||||
response.success
|
||||
) {
|
||||
if (
|
||||
'undefined' !== typeof response.data &&
|
||||
'undefined' !== typeof response.data.skipped &&
|
||||
true === response.data.skipped
|
||||
) {
|
||||
skippedItems++;
|
||||
}
|
||||
|
||||
currentStep++;
|
||||
remainingSteps = remainingSteps - 1;
|
||||
obj.onFinishStep( obj.getProgress() );
|
||||
step( remainingSteps ).fail( obj.showScanError );
|
||||
} else if (
|
||||
'undefined' !== typeof response.data.error &&
|
||||
'dir_smush_limit_exceeded' === response.data.error
|
||||
) {
|
||||
// Limit reached. Stop.
|
||||
obj.limitReached();
|
||||
} else {
|
||||
// Error? never mind, continue, but count them.
|
||||
failedItems++;
|
||||
currentStep++;
|
||||
remainingSteps = remainingSteps - 1;
|
||||
obj.onFinishStep( obj.getProgress() );
|
||||
step( remainingSteps ).fail( obj.showScanError );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return jQuery.post(
|
||||
ajaxurl,
|
||||
{
|
||||
action: 'directory_smush_finish',
|
||||
_ajax_nonce: window.wp_smush_msgs.nonce,
|
||||
items: totalSteps - ( failedItems + skippedItems ),
|
||||
failed: failedItems,
|
||||
skipped: skippedItems,
|
||||
},
|
||||
( response ) => obj.onFinish( response )
|
||||
);
|
||||
};
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
export default DirectoryScanner;
|
287
wp-content/plugins/wp-smushit/_src/js/smush/lazy-load.js
Normal file
287
wp-content/plugins/wp-smushit/_src/js/smush/lazy-load.js
Normal file
@ -0,0 +1,287 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* Lazy loading functionality.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.Lazyload = {
|
||||
lazyloadEnableButton: document.getElementById(
|
||||
'smush-enable-lazyload'
|
||||
),
|
||||
lazyloadDisableButton: document.getElementById(
|
||||
'smush-cancel-lazyload'
|
||||
),
|
||||
|
||||
init() {
|
||||
const self = this;
|
||||
|
||||
/**
|
||||
* Handle "Activate" button click on disabled Lazy load page.
|
||||
*/
|
||||
if ( this.lazyloadEnableButton ) {
|
||||
this.lazyloadEnableButton.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
e.currentTarget.classList.add( 'sui-button-onload' );
|
||||
|
||||
this.toggle_lazy_load( true );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "Deactivate' button click on Lazy load page.
|
||||
*/
|
||||
if ( this.lazyloadDisableButton ) {
|
||||
this.lazyloadDisableButton.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
e.currentTarget.classList.add( 'sui-button-onload' );
|
||||
|
||||
this.toggle_lazy_load( false );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "Remove icon" button click on Lazy load page.
|
||||
*
|
||||
* This removes the image from the upload placeholder.
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
const removeSpinner = document.getElementById(
|
||||
'smush-remove-spinner'
|
||||
);
|
||||
if ( removeSpinner ) {
|
||||
removeSpinner.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
this.removeLoaderIcon();
|
||||
} );
|
||||
}
|
||||
const removePlaceholder = document.getElementById(
|
||||
'smush-remove-placeholder'
|
||||
);
|
||||
if ( removePlaceholder ) {
|
||||
removePlaceholder.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
this.removeLoaderIcon( 'placeholder' );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "Remove" icon click.
|
||||
*
|
||||
* This removes the select icon from the list (not same as above functions).
|
||||
*
|
||||
* @since 3.2.2
|
||||
*/
|
||||
const items = document.querySelectorAll( '.smush-ll-remove' );
|
||||
if ( items && 0 < items.length ) {
|
||||
items.forEach( function( el ) {
|
||||
el.addEventListener( 'click', ( e ) => {
|
||||
e.preventDefault();
|
||||
e.target.closest( 'li' ).style.display = 'none';
|
||||
self.remove(
|
||||
e.target.dataset.id,
|
||||
e.target.dataset.type
|
||||
);
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
this.handlePredefinedPlaceholders();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle background color changes for the two predefined placeholders.
|
||||
*
|
||||
* @since 3.7.1
|
||||
*/
|
||||
handlePredefinedPlaceholders() {
|
||||
const pl1 = document.getElementById( 'placeholder-icon-1' );
|
||||
if ( pl1 ) {
|
||||
pl1.addEventListener( 'click', () => this.changeColor( '#F3F3F3' ) );
|
||||
}
|
||||
|
||||
const pl2 = document.getElementById( 'placeholder-icon-2' );
|
||||
if ( pl2 ) {
|
||||
pl2.addEventListener( 'click', () => this.changeColor( '#333333' ) );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set color.
|
||||
*
|
||||
* @since 3.7.1
|
||||
* @param {string} color
|
||||
*/
|
||||
changeColor( color ) {
|
||||
document.getElementById( 'smush-color-picker' ).value = color;
|
||||
document.querySelector( '.sui-colorpicker-hex .sui-colorpicker-value > span > span' ).style.backgroundColor = color;
|
||||
document.querySelector( '.sui-colorpicker-hex .sui-colorpicker-value > input' ).value = color;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle lazy loading.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param {string} enable
|
||||
*/
|
||||
toggle_lazy_load( enable ) {
|
||||
const nonceField = document.getElementsByName(
|
||||
'wp_smush_options_nonce'
|
||||
);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(
|
||||
'POST',
|
||||
ajaxurl + '?action=smush_toggle_lazy_load',
|
||||
true
|
||||
);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
const res = JSON.parse( xhr.response );
|
||||
if ( 'undefined' !== typeof res.success && res.success ) {
|
||||
window.location.search = 'page=smush-lazy-load';
|
||||
} else if ( 'undefined' !== typeof res.data.message ) {
|
||||
WP_Smush.helpers.showErrorNotice( res.data.message );
|
||||
document.querySelector( '.sui-button-onload' ).classList.remove( 'sui-button-onload' );
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status );
|
||||
document.querySelector( '.sui-button-onload' ).classList.remove( 'sui-button-onload' );
|
||||
}
|
||||
};
|
||||
xhr.send(
|
||||
'param=' + enable + '&_ajax_nonce=' + nonceField[ 0 ].value
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add lazy load spinner icon.
|
||||
*
|
||||
* @since 3.2.2
|
||||
* @param {string} type Accepts: spinner, placeholder.
|
||||
*/
|
||||
addLoaderIcon( type = 'spinner' ) {
|
||||
let frame;
|
||||
|
||||
// If the media frame already exists, reopen it.
|
||||
if ( frame ) {
|
||||
frame.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new media frame
|
||||
frame = wp.media( {
|
||||
title: 'Select or upload an icon',
|
||||
button: {
|
||||
text: 'Select icon',
|
||||
},
|
||||
multiple: false, // Set to true to allow multiple files to be selected
|
||||
} );
|
||||
|
||||
// When an image is selected in the media frame...
|
||||
frame.on( 'select', function() {
|
||||
// Get media attachment details from the frame state
|
||||
const attachment = frame
|
||||
.state()
|
||||
.get( 'selection' )
|
||||
.first()
|
||||
.toJSON();
|
||||
|
||||
// Send the attachment URL to our custom image input field.
|
||||
const imageIcon = document.getElementById(
|
||||
'smush-' + type + '-icon-preview'
|
||||
);
|
||||
imageIcon.style.backgroundImage =
|
||||
'url("' + attachment.url + '")';
|
||||
imageIcon.style.display = 'block';
|
||||
|
||||
// Send the attachment id to our hidden input
|
||||
document
|
||||
.getElementById( 'smush-' + type + '-icon-file' )
|
||||
.setAttribute( 'value', attachment.id );
|
||||
|
||||
// Hide the add image link
|
||||
document.getElementById(
|
||||
'smush-upload-' + type
|
||||
).style.display = 'none';
|
||||
|
||||
// Unhide the remove image link
|
||||
const removeDiv = document.getElementById(
|
||||
'smush-remove-' + type
|
||||
);
|
||||
removeDiv.querySelector( 'span' ).innerHTML =
|
||||
attachment.filename;
|
||||
removeDiv.style.display = 'block';
|
||||
} );
|
||||
|
||||
// Finally, open the modal on click
|
||||
frame.open();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove lazy load spinner icon.
|
||||
*
|
||||
* @since 3.2.2
|
||||
* @param {string} type Accepts: spinner, placeholder.
|
||||
*/
|
||||
removeLoaderIcon: ( type = 'spinner' ) => {
|
||||
// Clear out the preview image
|
||||
const imageIcon = document.getElementById(
|
||||
'smush-' + type + '-icon-preview'
|
||||
);
|
||||
imageIcon.style.backgroundImage = '';
|
||||
imageIcon.style.display = 'none';
|
||||
|
||||
// Un-hide the add image link
|
||||
document.getElementById( 'smush-upload-' + type ).style.display =
|
||||
'block';
|
||||
|
||||
// Hide the delete image link
|
||||
document.getElementById( 'smush-remove-' + type ).style.display =
|
||||
'none';
|
||||
|
||||
// Delete the image id from the hidden input
|
||||
document
|
||||
.getElementById( 'smush-' + type + '-icon-file' )
|
||||
.setAttribute( 'value', '' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove item.
|
||||
*
|
||||
* @param {number} id Image ID.
|
||||
* @param {string} type Accepts: spinner, placeholder.
|
||||
*/
|
||||
remove: ( id, type = 'spinner' ) => {
|
||||
const nonceField = document.getElementsByName(
|
||||
'wp_smush_options_nonce'
|
||||
);
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open( 'POST', ajaxurl + '?action=smush_remove_icon', true );
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.send(
|
||||
'id=' +
|
||||
id +
|
||||
'&type=' +
|
||||
type +
|
||||
'&_ajax_nonce=' +
|
||||
nonceField[ 0 ].value
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
WP_Smush.Lazyload.init();
|
||||
} )();
|
180
wp-content/plugins/wp-smushit/_src/js/smush/media.js
Normal file
180
wp-content/plugins/wp-smushit/_src/js/smush/media.js
Normal file
@ -0,0 +1,180 @@
|
||||
/* global smush_vars */
|
||||
/* global _ */
|
||||
|
||||
/**
|
||||
* Adds a Smush Now button and displays stats in Media Attachment Details Screen
|
||||
*/
|
||||
(function ($, _) {
|
||||
'use strict';
|
||||
|
||||
// Local reference to the WordPress media namespace.
|
||||
const smushMedia = wp.media,
|
||||
sharedTemplate =
|
||||
"<span class='setting smush-stats' data-setting='smush'>" +
|
||||
"<span class='name'><%= label %></span>" +
|
||||
"<span class='value'><%= value %></span>" +
|
||||
'</span>',
|
||||
template = _.template(sharedTemplate);
|
||||
|
||||
/**
|
||||
* Create the template.
|
||||
*
|
||||
* @param {string} smushHTML
|
||||
* @return {Object} Template object
|
||||
*/
|
||||
const prepareTemplate = function (smushHTML) {
|
||||
/**
|
||||
* @param {Array} smush_vars.strings Localization strings.
|
||||
* @param {Object} smush_vars Object from wp_localize_script()
|
||||
*/
|
||||
return template({
|
||||
label: smush_vars.strings.stats_label,
|
||||
value: smushHTML,
|
||||
});
|
||||
};
|
||||
|
||||
if (
|
||||
'undefined' !== typeof smushMedia.view &&
|
||||
'undefined' !== typeof smushMedia.view.Attachment.Details.TwoColumn
|
||||
) {
|
||||
// Local instance of the Attachment Details TwoColumn used in the edit attachment modal view
|
||||
const smushMediaTwoColumn =
|
||||
smushMedia.view.Attachment.Details.TwoColumn;
|
||||
|
||||
/**
|
||||
* Add Smush details to attachment.
|
||||
*
|
||||
* A similar view to media.view.Attachment.Details
|
||||
* for use in the Edit Attachment modal.
|
||||
*
|
||||
* @see wp-includes/js/media-grid.js
|
||||
*/
|
||||
smushMedia.view.Attachment.Details.TwoColumn = smushMediaTwoColumn.extend(
|
||||
{
|
||||
initialize() {
|
||||
smushMediaTwoColumn.prototype.initialize.apply(this, arguments);
|
||||
this.listenTo(this.model, 'change:smush', this.render);
|
||||
},
|
||||
|
||||
render() {
|
||||
// Ensure that the main attachment fields are rendered.
|
||||
smushMedia.view.Attachment.prototype.render.apply(
|
||||
this,
|
||||
arguments
|
||||
);
|
||||
|
||||
const smushHTML = this.model.get('smush');
|
||||
if (typeof smushHTML === 'undefined') {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.model.fetch();
|
||||
|
||||
/**
|
||||
* Detach the views, append our custom fields, make sure that our data is fully updated
|
||||
* and re-render the updated view.
|
||||
*/
|
||||
this.views.detach();
|
||||
this.$el
|
||||
.find('.settings')
|
||||
.append(prepareTemplate(smushHTML));
|
||||
this.views.render();
|
||||
|
||||
return this;
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Local instance of the Attachment Details TwoColumn used in the edit attachment modal view
|
||||
const smushAttachmentDetails = smushMedia.view.Attachment.Details;
|
||||
|
||||
/**
|
||||
* Add Smush details to attachment.
|
||||
*/
|
||||
smushMedia.view.Attachment.Details = smushAttachmentDetails.extend({
|
||||
initialize() {
|
||||
smushAttachmentDetails.prototype.initialize.apply(this, arguments);
|
||||
this.listenTo(this.model, 'change:smush', this.render);
|
||||
},
|
||||
|
||||
render() {
|
||||
// Ensure that the main attachment fields are rendered.
|
||||
smushMedia.view.Attachment.prototype.render.apply(this, arguments);
|
||||
|
||||
const smushHTML = this.model.get('smush');
|
||||
if (typeof smushHTML === 'undefined') {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.model.fetch();
|
||||
|
||||
/**
|
||||
* Detach the views, append our custom fields, make sure that our data is fully updated
|
||||
* and re-render the updated view.
|
||||
*/
|
||||
this.views.detach();
|
||||
this.$el.append(prepareTemplate(smushHTML));
|
||||
|
||||
return this;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a new MediaLibraryTaxonomyFilter we later will instantiate
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
const MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({
|
||||
id: 'media-attachment-smush-filter',
|
||||
|
||||
createFilters() {
|
||||
this.filters = {
|
||||
all: {
|
||||
text: smush_vars.strings.filter_all,
|
||||
props: { stats: 'all' },
|
||||
priority: 10,
|
||||
},
|
||||
|
||||
unsmushed: {
|
||||
text: smush_vars.strings.filter_not_processed,
|
||||
props: { stats: 'unsmushed' },
|
||||
priority: 20,
|
||||
},
|
||||
|
||||
excluded: {
|
||||
text: smush_vars.strings.filter_excl,
|
||||
props: { stats: 'excluded' },
|
||||
priority: 30,
|
||||
},
|
||||
|
||||
failed: {
|
||||
text: smush_vars.strings.filter_failed,
|
||||
props: { stats: 'failed_processing' },
|
||||
priority: 40,
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Extend and override wp.media.view.AttachmentsBrowser to include our new filter.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
const AttachmentsBrowser = wp.media.view.AttachmentsBrowser;
|
||||
wp.media.view.AttachmentsBrowser = wp.media.view.AttachmentsBrowser.extend({
|
||||
createToolbar() {
|
||||
// Make sure to load the original toolbar
|
||||
AttachmentsBrowser.prototype.createToolbar.call(this);
|
||||
this.toolbar.set(
|
||||
'MediaLibraryTaxonomyFilter',
|
||||
new MediaLibraryTaxonomyFilter({
|
||||
controller: this.controller,
|
||||
model: this.collection.props,
|
||||
priority: -75,
|
||||
}).render()
|
||||
);
|
||||
},
|
||||
});
|
||||
})(jQuery, _);
|
@ -0,0 +1,45 @@
|
||||
import MixPanel from "../mixpanel";
|
||||
|
||||
class ProductAnalytics {
|
||||
init() {
|
||||
this.trackUltraLinks();
|
||||
}
|
||||
|
||||
trackUltraLinks() {
|
||||
const ultraUpsellLinks = document.querySelectorAll( '.wp-smush-upsell-ultra-compression' );
|
||||
if ( ! ultraUpsellLinks ) {
|
||||
return;
|
||||
}
|
||||
const getLocation = ( ultraLink ) => {
|
||||
const locations = {
|
||||
'settings': 'bulksmush_settings',
|
||||
'dashboard': 'dash_summary',
|
||||
'bulk': 'bulksmush_summary',
|
||||
'directory': 'directory_summary',
|
||||
'lazy-load': 'lazy_summary',
|
||||
'cdn': 'cdn_summary',
|
||||
'webp': 'webp_summary',
|
||||
};
|
||||
const locationId = ultraLink.classList.contains( 'wp-smush-ultra-compression-link' ) ? 'settings' : this.getCurrentPageSlug();
|
||||
return locations[locationId] || 'bulksmush_settings';
|
||||
}
|
||||
|
||||
ultraUpsellLinks.forEach( ( ultraLink ) => {
|
||||
const eventName = 'ultra_upsell_modal';
|
||||
ultraLink.addEventListener( 'click', (e) => {
|
||||
MixPanel.getInstance().track( eventName, {
|
||||
'Location': getLocation( e.target ),
|
||||
'Modal Action': 'direct_cta',
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentPageSlug(){
|
||||
const searchParams = new URLSearchParams(document.location.search);
|
||||
const pageSlug = searchParams.get("page");
|
||||
return 'smush' === pageSlug ? 'dashboard' : pageSlug.replace( 'smush-', '' );
|
||||
}
|
||||
}
|
||||
|
||||
( new ProductAnalytics() ).init();
|
173
wp-content/plugins/wp-smushit/_src/js/smush/settings.js
Normal file
173
wp-content/plugins/wp-smushit/_src/js/smush/settings.js
Normal file
@ -0,0 +1,173 @@
|
||||
/* global ajaxurl */
|
||||
/* global wp_smush_msgs */
|
||||
/* global WP_Smush */
|
||||
/* global SUI */
|
||||
|
||||
( function( $ ) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Bulk compress page.
|
||||
*/
|
||||
$( 'form#smush-bulk-form' ).on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload' );
|
||||
saveSettings( $( this ).serialize(), 'bulk' );
|
||||
// runReCheck();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Lazy load page.
|
||||
*/
|
||||
$( 'form#smush-lazy-load-form' ).on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload-text' );
|
||||
saveSettings( $( this ).serialize(), 'lazy-load' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* CDN page.
|
||||
*/
|
||||
$( 'form#smush-cdn-form' ).on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload-text' );
|
||||
saveSettings( $( this ).serialize(), 'cdn' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Integrations page.
|
||||
*/
|
||||
$( 'form#smush-integrations-form' ).on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload-text' );
|
||||
saveSettings( $( this ).serialize(), 'integrations' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Settings page.
|
||||
*/
|
||||
$( 'form#smush-settings-form' ).on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload-text' );
|
||||
saveSettings( $( this ).serialize(), 'settings' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Save settings.
|
||||
*
|
||||
* @param {string} settings JSON string of settings.
|
||||
* @param {string} page Settings page.
|
||||
*/
|
||||
function saveSettings( settings, page ) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open( 'POST', ajaxurl + '?action=smush_save_settings', true );
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
xhr.onload = () => {
|
||||
$( '#save-settings-button' ).removeClass(
|
||||
'sui-button-onload-text sui-button-onload'
|
||||
);
|
||||
|
||||
if ( 200 === xhr.status ) {
|
||||
const res = JSON.parse( xhr.response );
|
||||
if ( 'undefined' !== typeof res.success && res.success ) {
|
||||
showSuccessNotice( wp_smush_msgs.settingsUpdated );
|
||||
triggerSavedSmushSettingsEvent( res.data );
|
||||
} else if ( res.data && res.data.message ) {
|
||||
WP_Smush.helpers.showErrorNotice( res.data.message );
|
||||
} else {
|
||||
WP_Smush.helpers.showErrorNotice( 'Request failed.' );
|
||||
}
|
||||
} else {
|
||||
WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status );
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send( 'page=' + page + '&' + settings + '&_ajax_nonce=' + wp_smush_msgs.nonce );
|
||||
}
|
||||
|
||||
function triggerSavedSmushSettingsEvent( status ) {
|
||||
document.dispatchEvent(
|
||||
new CustomEvent( 'onSavedSmushSettings', {
|
||||
detail: status
|
||||
} )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show successful update notice.
|
||||
*
|
||||
* @param {string} msg Notice message.
|
||||
*/
|
||||
function showSuccessNotice( msg ) {
|
||||
const noticeMessage = `<p>${ msg }</p>`,
|
||||
noticeOptions = {
|
||||
type: 'success',
|
||||
icon: 'check',
|
||||
};
|
||||
|
||||
SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions );
|
||||
|
||||
const loadingButton = document.querySelector( '.sui-button-onload' );
|
||||
if ( loadingButton ) {
|
||||
loadingButton.classList.remove( 'sui-button-onload' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-check images from bulk smush and integrations pages.
|
||||
*/
|
||||
function runReCheck() {
|
||||
$( '#save-settings-button' ).addClass( 'sui-button-onload' );
|
||||
|
||||
const param = {
|
||||
action: 'scan_for_resmush',
|
||||
wp_smush_options_nonce: $( '#wp_smush_options_nonce' ).val(),
|
||||
type: 'media',
|
||||
};
|
||||
|
||||
// Send ajax, Update Settings, And Check For resmush.
|
||||
$.post( ajaxurl, $.param( param ) ).done( function() {
|
||||
$( '#save-settings-button' ).removeClass( 'sui-button-onload' );
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse remove data change.
|
||||
*/
|
||||
$( 'input[name=keep_data]' ).on( 'change', function( e ) {
|
||||
const otherClass =
|
||||
'keep_data-true' === e.target.id
|
||||
? 'keep_data-false'
|
||||
: 'keep_data-true';
|
||||
e.target.parentNode.classList.add( 'active' );
|
||||
document
|
||||
.getElementById( otherClass )
|
||||
.parentNode.classList.remove( 'active' );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Handle auto-detect checkbox toggle, to show/hide highlighting notice.
|
||||
*/
|
||||
$( 'input#detection' ).on( 'click', function() {
|
||||
const noticeDiv = $( '.smush-highlighting-notice' );
|
||||
const warningDiv = $( '.smush-highlighting-warning' );
|
||||
|
||||
// Setting enabled.
|
||||
if ( $( this ).is( ':checked' ) ) {
|
||||
// Highlighting is already active and setting not saved.
|
||||
if ( noticeDiv.length > 0 ) {
|
||||
noticeDiv.show();
|
||||
} else {
|
||||
warningDiv.show();
|
||||
}
|
||||
} else {
|
||||
noticeDiv.hide();
|
||||
warningDiv.hide();
|
||||
}
|
||||
} );
|
||||
}( jQuery ) );
|
1210
wp-content/plugins/wp-smushit/_src/js/smush/smush.js
Normal file
1210
wp-content/plugins/wp-smushit/_src/js/smush/smush.js
Normal file
File diff suppressed because it is too large
Load Diff
311
wp-content/plugins/wp-smushit/_src/js/smush/webp.js
Normal file
311
wp-content/plugins/wp-smushit/_src/js/smush/webp.js
Normal file
@ -0,0 +1,311 @@
|
||||
/* global WP_Smush */
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* WebP functionality.
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
WP_Smush.WebP = {
|
||||
nonceField: document.getElementsByName('wp_smush_options_nonce'),
|
||||
toggleModuleButton: document.getElementById('smush-toggle-webp-button'),
|
||||
recheckStatusButton: document.getElementById('smush-webp-recheck'),
|
||||
recheckStatusLink: document.getElementById('smush-webp-recheck-link'),
|
||||
showWizardButton: document.getElementById('smush-webp-toggle-wizard'),
|
||||
|
||||
init() {
|
||||
this.maybeShowDeleteAllSuccessNotice();
|
||||
|
||||
/**
|
||||
* Handles the "Deactivate" and "Get Started" buttons on the WebP page.
|
||||
*/
|
||||
if (this.toggleModuleButton) {
|
||||
this.toggleModuleButton.addEventListener('click', (e) =>
|
||||
this.toggleWebp(e)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "RE-CHECK STATUS' button click on WebP page.
|
||||
*/
|
||||
if (this.recheckStatusButton) {
|
||||
this.recheckStatusButton.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.recheckStatus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle "RE-CHECK STATUS' link click on WebP page.
|
||||
*/
|
||||
if (this.recheckStatusLink) {
|
||||
this.recheckStatusLink.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.recheckStatus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "Delete WebP images" button.
|
||||
*/
|
||||
if (document.getElementById('wp-smush-webp-delete-all')) {
|
||||
document
|
||||
.getElementById('wp-smush-webp-delete-all')
|
||||
.addEventListener('click', (e) => this.deleteAll(e));
|
||||
}
|
||||
|
||||
if (this.showWizardButton) {
|
||||
this.showWizardButton.addEventListener(
|
||||
'click',
|
||||
this.toggleWizard
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle WebP module.
|
||||
*
|
||||
* @param {Event} e
|
||||
*/
|
||||
toggleWebp(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const button = e.currentTarget,
|
||||
doEnable = 'enable' === button.dataset.action;
|
||||
|
||||
button.classList.add('sui-button-onload');
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', ajaxurl + '?action=smush_webp_toggle', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
xhr.onload = () => {
|
||||
const res = JSON.parse(xhr.response);
|
||||
|
||||
if (200 === xhr.status) {
|
||||
if ('undefined' !== typeof res.success && res.success) {
|
||||
const scanPromise = this.runScan();
|
||||
scanPromise.onload = () => {
|
||||
window.location.href =
|
||||
window.wp_smush_msgs.localWebpURL;
|
||||
};
|
||||
} else if ('undefined' !== typeof res.data.message) {
|
||||
this.showNotice(res.data.message);
|
||||
button.classList.remove('sui-button-onload');
|
||||
}
|
||||
} else {
|
||||
let message = window.wp_smush_msgs.generic_ajax_error;
|
||||
if (res && 'undefined' !== typeof res.data.message) {
|
||||
message = res.data.message;
|
||||
}
|
||||
this.showNotice(message);
|
||||
button.classList.remove('sui-button-onload');
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(
|
||||
'param=' + doEnable + '&_ajax_nonce=' + this.nonceField[0].value
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* re-check server configuration for WebP.
|
||||
*/
|
||||
recheckStatus() {
|
||||
this.recheckStatusButton.classList.add('sui-button-onload');
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', ajaxurl + '?action=smush_webp_get_status', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
xhr.onload = () => {
|
||||
this.recheckStatusButton.classList.remove('sui-button-onload');
|
||||
let message = false;
|
||||
const res = JSON.parse(xhr.response);
|
||||
if (200 === xhr.status) {
|
||||
const isConfigured = res.success ? '1' : '0';
|
||||
if (
|
||||
isConfigured !==
|
||||
this.recheckStatusButton.dataset.isConfigured
|
||||
) {
|
||||
// Reload the page when the configuration status changed.
|
||||
location.reload();
|
||||
}
|
||||
} else {
|
||||
message = window.wp_smush_msgs.generic_ajax_error;
|
||||
}
|
||||
|
||||
if (res && res.data) {
|
||||
message = res.data;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
this.showNotice(message);
|
||||
}
|
||||
};
|
||||
xhr.send('_ajax_nonce=' + window.wp_smush_msgs.webp_nonce);
|
||||
},
|
||||
|
||||
deleteAll(e) {
|
||||
const button = e.currentTarget;
|
||||
button.classList.add('sui-button-onload');
|
||||
|
||||
let message = false;
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', ajaxurl + '?action=smush_webp_delete_all', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
xhr.onload = () => {
|
||||
const res = JSON.parse(xhr.response);
|
||||
if (200 === xhr.status) {
|
||||
if ('undefined' !== typeof res.success && res.success) {
|
||||
const scanPromise = this.runScan();
|
||||
scanPromise.onload = () => {
|
||||
location.search =
|
||||
location.search + '¬ice=webp-deleted';
|
||||
};
|
||||
} else {
|
||||
message = window.wp_smush_msgs.generic_ajax_error;
|
||||
}
|
||||
} else {
|
||||
message = window.wp_smush_msgs.generic_ajax_error;
|
||||
}
|
||||
|
||||
if (res && res.data && res.data.message) {
|
||||
message = res.data.message;
|
||||
}
|
||||
|
||||
if (message) {
|
||||
button.classList.remove('sui-button-onload');
|
||||
|
||||
const noticeMessage = `<p style="text-align: left;">${message}</p>`;
|
||||
const noticeOptions = {
|
||||
type: 'error',
|
||||
icon: 'info',
|
||||
autoclose: {
|
||||
show: false,
|
||||
},
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-webp-delete-all-error-notice',
|
||||
noticeMessage,
|
||||
noticeOptions
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send('_ajax_nonce=' + this.nonceField[0].value);
|
||||
},
|
||||
|
||||
toggleWizard(e) {
|
||||
e.currentTarget.classList.add('sui-button-onload');
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(
|
||||
'GET',
|
||||
ajaxurl +
|
||||
'?action=smush_toggle_webp_wizard&_ajax_nonce=' +
|
||||
window.wp_smush_msgs.webp_nonce,
|
||||
true
|
||||
);
|
||||
xhr.onload = () => location.reload();
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers the scanning of images for updating the images to re-smush.
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
runScan() {
|
||||
const xhr = new XMLHttpRequest(),
|
||||
nonceField = document.getElementsByName(
|
||||
'wp_smush_options_nonce'
|
||||
);
|
||||
|
||||
xhr.open('POST', ajaxurl + '?action=scan_for_resmush', true);
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
xhr.send('_ajax_nonce=' + nonceField[0].value);
|
||||
|
||||
return xhr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Show message (notice).
|
||||
*
|
||||
* @param {string} message
|
||||
* @param {string} type
|
||||
*/
|
||||
showNotice(message, type) {
|
||||
if ('undefined' === typeof message) {
|
||||
return;
|
||||
}
|
||||
|
||||
const noticeMessage = `<p>${message}</p>`;
|
||||
const noticeOptions = {
|
||||
type: type || 'error',
|
||||
icon: 'info',
|
||||
dismiss: {
|
||||
show: true,
|
||||
label: window.wp_smush_msgs.noticeDismiss,
|
||||
tooltip: window.wp_smush_msgs.noticeDismissTooltip,
|
||||
},
|
||||
autoclose: {
|
||||
show: false,
|
||||
},
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-ajax-notice',
|
||||
noticeMessage,
|
||||
noticeOptions
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show delete all webp success notice.
|
||||
*/
|
||||
maybeShowDeleteAllSuccessNotice() {
|
||||
if (!document.getElementById('wp-smush-webp-delete-all-notice')) {
|
||||
return;
|
||||
}
|
||||
const noticeMessage = `<p>${
|
||||
document.getElementById('wp-smush-webp-delete-all-notice')
|
||||
.dataset.message
|
||||
}</p>`;
|
||||
|
||||
const noticeOptions = {
|
||||
type: 'success',
|
||||
icon: 'check-tick',
|
||||
dismiss: {
|
||||
show: true,
|
||||
},
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-webp-delete-all-notice',
|
||||
noticeMessage,
|
||||
noticeOptions
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
WP_Smush.WebP.init();
|
||||
})();
|
96
wp-content/plugins/wp-smushit/_src/js/tutorials.js
Normal file
96
wp-content/plugins/wp-smushit/_src/js/tutorials.js
Normal file
@ -0,0 +1,96 @@
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
|
||||
/**
|
||||
* SUI dependencies
|
||||
*/
|
||||
import { TutorialsList, TutorialsSlider } from '@wpmudev/shared-tutorials';
|
||||
|
||||
import MixPanel from "./mixpanel"
|
||||
|
||||
function hideTutorials() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
|
||||
xhr.open( 'POST', ajaxurl + '?action=smush_hide_tutorials', true );
|
||||
xhr.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded' );
|
||||
|
||||
xhr.onload = () => {
|
||||
if ( 200 === xhr.status ) {
|
||||
const noticeMessage = `<p>${ window.wp_smush_msgs.tutorialsRemoved }</p>`,
|
||||
noticeOptions = {
|
||||
type: 'success',
|
||||
icon: 'check',
|
||||
};
|
||||
|
||||
window.SUI.openNotice(
|
||||
'wp-smush-ajax-notice',
|
||||
noticeMessage,
|
||||
noticeOptions
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send( '_ajax_nonce=' + window.wp_smush_msgs.nonce );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the "Tutorials List" component.
|
||||
*
|
||||
* @since 2.8.5
|
||||
*/
|
||||
domReady( function() {
|
||||
// Tutorials section on Dashboard page.
|
||||
const tutorialsDiv = document.getElementById( 'smush-dash-tutorials' );
|
||||
if ( tutorialsDiv ) {
|
||||
ReactDOM.render(
|
||||
<TutorialsSlider
|
||||
category="11228"
|
||||
title={ window.smush_tutorials.tutorials }
|
||||
viewAll={ window.smush_tutorials.tutorials_link }
|
||||
onCloseClick={ hideTutorials }
|
||||
/>,
|
||||
tutorialsDiv
|
||||
);
|
||||
}
|
||||
|
||||
// Tutorials page.
|
||||
const tutorialsPageBox = document.getElementById( 'smush-box-tutorials' );
|
||||
if ( tutorialsPageBox ) {
|
||||
ReactDOM.render(
|
||||
<TutorialsList
|
||||
category="11228"
|
||||
title={ window.smush_tutorials.tutorials }
|
||||
translate={ window.smush_tutorials.tutorials_strings }
|
||||
/>,
|
||||
tutorialsPageBox
|
||||
);
|
||||
}
|
||||
} );
|
||||
|
||||
jQuery(function ($) {
|
||||
$(document).on('click', '#smush-box-tutorials li > [role="link"], #smush-dash-tutorials li > [role="link"]', function () {
|
||||
const $tutorial = $(this);
|
||||
const isDashPage = !!$tutorial.closest('#smush-dash-tutorials').length;
|
||||
const decodeHtml = (html) => {
|
||||
const txt = document.createElement("textarea");
|
||||
txt.innerHTML = html;
|
||||
return txt.value;
|
||||
};
|
||||
const title = decodeHtml($tutorial.attr('title'));
|
||||
|
||||
MixPanel.getInstance().track('Tutorial Opened', {
|
||||
'Tutorial Name': title,
|
||||
'Triggered From': isDashPage ? 'Dashboard' : 'Tutorials Tab'
|
||||
});
|
||||
});
|
||||
});
|
170
wp-content/plugins/wp-smushit/_src/js/utils/fetcher.js
Normal file
170
wp-content/plugins/wp-smushit/_src/js/utils/fetcher.js
Normal file
@ -0,0 +1,170 @@
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import assign from 'lodash/assign';
|
||||
|
||||
/**
|
||||
* Wrapper function for ajax calls to WordPress.
|
||||
*
|
||||
* @since 3.12.0
|
||||
*/
|
||||
function SmushFetcher() {
|
||||
/**
|
||||
* Request ajax with a promise.
|
||||
* Use FormData Object as data if you need to upload file
|
||||
*
|
||||
* @param {string} action
|
||||
* @param {Object|FormData} data
|
||||
* @param {string} method
|
||||
* @return {Promise<any>} Request results.
|
||||
*/
|
||||
function request(action, data = {}, method = 'POST') {
|
||||
const args = {
|
||||
url: ajaxurl,
|
||||
method,
|
||||
cache: false
|
||||
};
|
||||
|
||||
if (data instanceof FormData) {
|
||||
data.append('action', action);
|
||||
data.append('_ajax_nonce', window.wp_smush_msgs.nonce);
|
||||
args.contentType = false;
|
||||
args.processData = false;
|
||||
} else {
|
||||
data._ajax_nonce = data._ajax_nonce || window.wp_smush_msgs.nonce;
|
||||
data.action = action;
|
||||
}
|
||||
args.data = data;
|
||||
return new Promise((resolve, reject) => {
|
||||
jQuery.ajax(args).done(resolve).fail(reject);
|
||||
}).then((response) => {
|
||||
if (typeof response !== 'object') {
|
||||
response = JSON.parse(response);
|
||||
}
|
||||
return response;
|
||||
}).catch((error) => {
|
||||
console.error('Error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
const methods = {
|
||||
/**
|
||||
* Manage ajax for background.
|
||||
*/
|
||||
background: {
|
||||
/**
|
||||
* Start background process.
|
||||
*/
|
||||
start: () => {
|
||||
return request('bulk_smush_start');
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel background process.
|
||||
*/
|
||||
cancel: () => {
|
||||
return request('bulk_smush_cancel');
|
||||
},
|
||||
|
||||
/**
|
||||
* Initial State - Get stats on the first time.
|
||||
*/
|
||||
initState: () => {
|
||||
return request('bulk_smush_get_status');
|
||||
},
|
||||
|
||||
/**
|
||||
* Get stats.
|
||||
*/
|
||||
getStatus: () => {
|
||||
return request('bulk_smush_get_status');
|
||||
},
|
||||
|
||||
getStats: () => {
|
||||
return request('bulk_smush_get_global_stats');
|
||||
}
|
||||
},
|
||||
smush: {
|
||||
/**
|
||||
* Sync stats.
|
||||
*/
|
||||
syncStats: ( data ) => {
|
||||
data = data || {};
|
||||
return request('get_stats', data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Ignore All.
|
||||
*/
|
||||
ignoreAll: ( type ) => {
|
||||
return request('wp_smush_ignore_all_failed_items', {
|
||||
type: type,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Manage ajax for other requests
|
||||
*/
|
||||
common: {
|
||||
/**
|
||||
* Dismiss Notice.
|
||||
*
|
||||
* @param {string} dismissId Notification id.
|
||||
*/
|
||||
dismissNotice: (dismissId) => {
|
||||
return request('smush_dismiss_notice', {
|
||||
key: dismissId
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Hide the new features modal.
|
||||
*
|
||||
* @param {string} modalID Notification id.
|
||||
*/
|
||||
hideModal: (modalID) => request('hide_modal', {
|
||||
modal_id: modalID,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Custom request.
|
||||
*
|
||||
* @param {Object} data
|
||||
*/
|
||||
request: (data) => data.action && request(data.action, data),
|
||||
},
|
||||
|
||||
scanMediaLibrary: {
|
||||
start: ( optimize_on_scan_completed = false ) => {
|
||||
optimize_on_scan_completed = optimize_on_scan_completed ? 1 : 0;
|
||||
const _ajax_nonce = window.wp_smushit_data.media_library_scan.nonce;
|
||||
return request( 'wp_smush_start_background_scan', {
|
||||
optimize_on_scan_completed,
|
||||
_ajax_nonce,
|
||||
} );
|
||||
},
|
||||
|
||||
cancel: () => {
|
||||
const _ajax_nonce = window.wp_smushit_data.media_library_scan.nonce;
|
||||
return request( 'wp_smush_cancel_background_scan', {
|
||||
_ajax_nonce,
|
||||
} );
|
||||
},
|
||||
|
||||
getScanStatus: () => {
|
||||
const _ajax_nonce = window.wp_smushit_data.media_library_scan.nonce;
|
||||
return request( 'wp_smush_get_background_scan_status', {
|
||||
_ajax_nonce,
|
||||
} );
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
assign(this, methods);
|
||||
}
|
||||
|
||||
const SmushAjax = new SmushFetcher();
|
||||
export default SmushAjax;
|
@ -0,0 +1,91 @@
|
||||
import React, {useEffect, useRef, useState} from "react";
|
||||
import {post} from "../utils/request";
|
||||
import MediaLibraryScannerModal from "./media-library-scanner-modal";
|
||||
|
||||
export default function AjaxMediaLibraryScannerModal(
|
||||
{
|
||||
nonce = '',
|
||||
onScanCompleted = () => false,
|
||||
onClose = () => false,
|
||||
focusAfterClose = ''
|
||||
}
|
||||
) {
|
||||
const [inProgress, setInProgress] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [cancelled, setCancelled] = useState(false);
|
||||
const cancelledRef = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
cancelledRef.current = cancelled;
|
||||
}, [cancelled]);
|
||||
|
||||
function start() {
|
||||
setInProgress(true);
|
||||
|
||||
post('wp_smush_before_scan_library', nonce).then((response) => {
|
||||
const sliceCount = response?.slice_count;
|
||||
const slicesList = range(sliceCount, 1);
|
||||
const parallelRequests = response?.parallel_requests;
|
||||
|
||||
handleBatch(slicesList, sliceCount, parallelRequests)
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
onScanCompleted();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleBatch(remainingSlicesList, sliceCount, parallelRequests) {
|
||||
const batchPromises = [];
|
||||
const completedSliceCount = Math.max(sliceCount - remainingSlicesList.length, 0);
|
||||
const batch = remainingSlicesList.splice(0, parallelRequests);
|
||||
|
||||
updateProgress(completedSliceCount, sliceCount);
|
||||
|
||||
batch.forEach((sliceNumber) => {
|
||||
batchPromises.push(
|
||||
post('wp_smush_scan_library_slice', nonce, {slice: sliceNumber})
|
||||
);
|
||||
});
|
||||
|
||||
return new Promise((resolve) => {
|
||||
Promise.all(batchPromises)
|
||||
.then(() => {
|
||||
if (!cancelledRef.current) {
|
||||
if (remainingSlicesList.length) {
|
||||
handleBatch(remainingSlicesList, sliceCount, parallelRequests)
|
||||
.then(resolve);
|
||||
} else {
|
||||
updateProgress(sliceCount, sliceCount);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function range(size, startAt = 0) {
|
||||
return [...Array(size).keys()].map(i => i + startAt);
|
||||
}
|
||||
|
||||
function cancelScan() {
|
||||
setCancelled(true);
|
||||
setInProgress(false);
|
||||
setProgress(0);
|
||||
}
|
||||
|
||||
function updateProgress(completedSlices, totalSlices) {
|
||||
const progress = (completedSlices / totalSlices) * 100;
|
||||
setProgress(progress);
|
||||
}
|
||||
|
||||
return <MediaLibraryScannerModal
|
||||
inProgress={inProgress}
|
||||
progress={progress}
|
||||
onCancel={cancelScan}
|
||||
focusAfterClose={focusAfterClose}
|
||||
onClose={onClose}
|
||||
onStart={start}
|
||||
/>;
|
||||
};
|
@ -0,0 +1,76 @@
|
||||
import React, {useRef, useState} from "react";
|
||||
import {post} from "../utils/request";
|
||||
import MediaLibraryScannerModal from "./media-library-scanner-modal";
|
||||
|
||||
export default function BackgroundMediaLibraryScannerModal(
|
||||
{
|
||||
nonce = '',
|
||||
onScanCompleted = () => false,
|
||||
onClose = () => false,
|
||||
focusAfterClose = ''
|
||||
}
|
||||
) {
|
||||
const [inProgress, setInProgress] = useState(false);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const [cancelled, setCancelled] = useState(false);
|
||||
const progressTimeoutId = useRef(0);
|
||||
|
||||
function start() {
|
||||
post('wp_smush_start_background_scan', nonce).then(() => {
|
||||
setInProgress(true);
|
||||
progressTimeoutId.current = setTimeout(updateProgress, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
function clearProgressTimeout() {
|
||||
if (progressTimeoutId.current) {
|
||||
clearTimeout(progressTimeoutId.current);
|
||||
}
|
||||
}
|
||||
|
||||
function updateProgress() {
|
||||
post('wp_smush_get_background_scan_status', nonce).then(response => {
|
||||
const isCompleted = response?.is_completed;
|
||||
if (isCompleted) {
|
||||
clearProgressTimeout();
|
||||
onScanCompleted();
|
||||
return;
|
||||
}
|
||||
|
||||
const isCancelled = response?.is_cancelled;
|
||||
if (isCancelled) {
|
||||
clearProgressTimeout();
|
||||
changeStateToCancelled();
|
||||
return;
|
||||
}
|
||||
|
||||
const totalItems = response?.total_items;
|
||||
const processedItems = response?.processed_items;
|
||||
const progress = (processedItems / totalItems) * 100;
|
||||
setProgress(progress);
|
||||
|
||||
progressTimeoutId.current = setTimeout(updateProgress, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function cancelScan() {
|
||||
clearProgressTimeout();
|
||||
post('wp_smush_cancel_background_scan', nonce)
|
||||
.then(changeStateToCancelled);
|
||||
}
|
||||
|
||||
function changeStateToCancelled() {
|
||||
setCancelled(true);
|
||||
setProgress(0);
|
||||
setInProgress(false);
|
||||
}
|
||||
|
||||
return <MediaLibraryScannerModal
|
||||
inProgress={inProgress}
|
||||
progress={progress}
|
||||
onCancel={cancelScan}
|
||||
focusAfterClose={focusAfterClose}
|
||||
onClose={onClose}
|
||||
onStart={start}
|
||||
/>;
|
||||
};
|
@ -0,0 +1,49 @@
|
||||
import React, {useEffect, useRef, useState} from "react";
|
||||
import Modal from "../common/modal";
|
||||
import {post} from "../utils/request";
|
||||
import Button from "../common/button";
|
||||
import ProgressBar from "../common/progress-bar";
|
||||
|
||||
const {__} = wp.i18n;
|
||||
|
||||
export default function MediaLibraryScannerModal(
|
||||
{
|
||||
inProgress = false,
|
||||
progress = 0,
|
||||
onClose = () => false,
|
||||
onStart = () => false,
|
||||
onCancel = () => false,
|
||||
focusAfterClose = ''
|
||||
}
|
||||
) {
|
||||
function content() {
|
||||
if (inProgress) {
|
||||
return <>
|
||||
<ProgressBar progress={progress}/>
|
||||
<Button id="wp-smush-cancel-media-library-scan"
|
||||
icon="sui-icon-close"
|
||||
text={__('Cancel', 'wp-smushit')}
|
||||
ghost={true}
|
||||
onClick={onCancel}
|
||||
/>
|
||||
</>;
|
||||
} else {
|
||||
return <>
|
||||
<Button id="wp-smush-start-media-library-scan"
|
||||
icon="sui-icon-play"
|
||||
text={__('Start', 'wp-smushit')}
|
||||
onClick={onStart}
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
}
|
||||
|
||||
return <Modal id="wp-smush-media-library-scanner-modal"
|
||||
title={__('Scan Media Library', 'wp-smushit')}
|
||||
description={__('Scans the media library to detect items to Smush.', 'wp-smushit')}
|
||||
onClose={onClose}
|
||||
focusAfterClose={focusAfterClose}
|
||||
disableCloseButton={inProgress}>
|
||||
{content()}
|
||||
</Modal>;
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
import React, {useState} from "react";
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
import ReactDOM from "react-dom";
|
||||
import Button from "../common/button";
|
||||
import FloatingNoticePlaceholder from "../common/floating-notice-placeholder";
|
||||
import {showSuccessNotice} from "../utils/notices";
|
||||
import AjaxMediaLibraryScannerModal from "./ajax-media-library-scanner-modal";
|
||||
import BackgroundMediaLibraryScannerModal from "./background-media-library-scanner-modal";
|
||||
|
||||
const {__} = wp.i18n;
|
||||
|
||||
function MediaLibraryScanner({}) {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
|
||||
return <>
|
||||
<FloatingNoticePlaceholder id="wp-smush-media-library-scanner-notice"/>
|
||||
|
||||
{modalOpen &&
|
||||
<BackgroundMediaLibraryScannerModal
|
||||
focusAfterClose="wp-smush-open-media-library-scanner"
|
||||
nonce={mediaLibraryScan.nonce}
|
||||
onScanCompleted={() => {
|
||||
showSuccessNotice(
|
||||
'wp-smush-media-library-scanner-notice',
|
||||
__('Scan completed successfully!', 'wp-smushit'),
|
||||
true
|
||||
);
|
||||
setModalOpen(false);
|
||||
window.location.reload();
|
||||
}}
|
||||
onClose={() => setModalOpen(false)}
|
||||
/>
|
||||
}
|
||||
|
||||
<Button id="wp-smush-open-media-library-scanner" text={__('Re-Check Images', 'wp-smushit')}
|
||||
className="wp-smush-scan"
|
||||
icon="sui-icon-update"
|
||||
disabled={modalOpen}
|
||||
onClick={() => setModalOpen(true)}
|
||||
/>
|
||||
</>;
|
||||
}
|
||||
|
||||
domReady(function () {
|
||||
const scannerContainer = document.getElementById('wp-smush-media-library-scanner');
|
||||
if (scannerContainer) {
|
||||
ReactDOM.render(
|
||||
<MediaLibraryScanner/>,
|
||||
scannerContainer
|
||||
);
|
||||
}
|
||||
});
|
70
wp-content/plugins/wp-smushit/_src/react/common/button.js
Normal file
70
wp-content/plugins/wp-smushit/_src/react/common/button.js
Normal file
@ -0,0 +1,70 @@
|
||||
import React from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
export default function Button(
|
||||
{
|
||||
id = "",
|
||||
text = "",
|
||||
color = "",
|
||||
dashed = false,
|
||||
icon = '',
|
||||
loading = false,
|
||||
ghost = false,
|
||||
disabled = false,
|
||||
href = "",
|
||||
target = "",
|
||||
className = "",
|
||||
onClick = () => false,
|
||||
}
|
||||
) {
|
||||
function handleClick(e) {
|
||||
e.preventDefault();
|
||||
|
||||
onClick();
|
||||
}
|
||||
|
||||
function textTag() {
|
||||
const iconTag = icon ? <span className={icon} aria-hidden="true"/> : "";
|
||||
return (
|
||||
<span className={classnames({"sui-loading-text": loading})}>
|
||||
{iconTag} {text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function loadingIcon() {
|
||||
return loading
|
||||
? <span className="sui-icon-loader sui-loading" aria-hidden="true"/>
|
||||
: "";
|
||||
}
|
||||
|
||||
let HtmlTag, props;
|
||||
if (href) {
|
||||
HtmlTag = 'a';
|
||||
props = {href: href, target: target};
|
||||
} else {
|
||||
HtmlTag = 'button';
|
||||
props = {
|
||||
disabled: disabled,
|
||||
onClick: e => handleClick(e)
|
||||
};
|
||||
}
|
||||
const hasText = text && text.trim();
|
||||
|
||||
return (
|
||||
<HtmlTag
|
||||
{...props}
|
||||
className={classnames(className, "sui-button-" + color, {
|
||||
"sui-button-onload": loading,
|
||||
"sui-button-ghost": ghost,
|
||||
"sui-button-icon": !hasText,
|
||||
"sui-button-dashed": dashed,
|
||||
"sui-button": hasText
|
||||
})}
|
||||
id={id}
|
||||
>
|
||||
{textTag()}
|
||||
{loadingIcon()}
|
||||
</HtmlTag>
|
||||
);
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
|
||||
export default function FloatingNoticePlaceholder({id = ''}) {
|
||||
return <div className="sui-floating-notices">
|
||||
<div role="alert"
|
||||
id={id}
|
||||
className="sui-notice"
|
||||
aria-live="assertive">
|
||||
</div>
|
||||
</div>;
|
||||
}
|
133
wp-content/plugins/wp-smushit/_src/react/common/modal.js
Normal file
133
wp-content/plugins/wp-smushit/_src/react/common/modal.js
Normal file
@ -0,0 +1,133 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import classnames from 'classnames';
|
||||
import SUI from 'SUI';
|
||||
import $ from 'jquery';
|
||||
|
||||
const {__} = wp.i18n;
|
||||
|
||||
export default function Modal(
|
||||
{
|
||||
id = '',
|
||||
title = '',
|
||||
description = '',
|
||||
small = false,
|
||||
headerActions = false,
|
||||
focusAfterOpen = '',
|
||||
focusAfterClose = 'container',
|
||||
dialogClasses = [],
|
||||
disableCloseButton = false,
|
||||
enterDisabled = false,
|
||||
beforeTitle = false,
|
||||
onEnter = () => false,
|
||||
onClose = () => false,
|
||||
footer,
|
||||
children
|
||||
}
|
||||
) {
|
||||
useEffect(() => {
|
||||
SUI.openModal(
|
||||
id,
|
||||
focusAfterClose,
|
||||
focusAfterOpen ? focusAfterOpen : getTitleId(),
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
return () => SUI.closeModal();
|
||||
}, []);
|
||||
|
||||
const handleKeyDown = (event) => {
|
||||
const isTargetInput = $(event.target).is('.sui-modal.sui-active input');
|
||||
if (isTargetInput && event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (!enterDisabled && onEnter) {
|
||||
onEnter(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTitleId() {
|
||||
return id + '-modal-title';
|
||||
}
|
||||
|
||||
function getHeaderActions() {
|
||||
const closeButton = getCloseButton();
|
||||
if (small) {
|
||||
return closeButton;
|
||||
} else if (headerActions) {
|
||||
return headerActions;
|
||||
} else {
|
||||
return <div className="sui-actions-right">{closeButton}</div>
|
||||
}
|
||||
}
|
||||
|
||||
function getCloseButton() {
|
||||
return <button id={id + '-close-button'}
|
||||
type="button"
|
||||
onClick={() => onClose()}
|
||||
disabled={disableCloseButton}
|
||||
className={classnames("sui-button-icon", {
|
||||
'sui-button-float--right': small
|
||||
})}>
|
||||
|
||||
<span className="sui-icon-close sui-md" aria-hidden="true"/>
|
||||
<span className="sui-screen-reader-text">
|
||||
{__('Close this dialog window', 'wds')}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
|
||||
function getDialogClasses() {
|
||||
return Object.assign({}, {
|
||||
'sui-modal-sm': small,
|
||||
'sui-modal-lg': !small
|
||||
}, dialogClasses);
|
||||
}
|
||||
|
||||
return <div className={classnames('sui-modal', getDialogClasses())}
|
||||
onKeyDown={e => handleKeyDown(e)}>
|
||||
<div role="dialog"
|
||||
id={id}
|
||||
className={classnames('sui-modal-content', id + '-modal')}
|
||||
aria-modal="true"
|
||||
aria-labelledby={id + '-modal-title'}
|
||||
aria-describedby={id + '-modal-description'}>
|
||||
|
||||
<div className="sui-box" role="document">
|
||||
<div className={classnames('sui-box-header', {
|
||||
'sui-flatten sui-content-center sui-spacing-top--40': small
|
||||
})}>
|
||||
{beforeTitle}
|
||||
|
||||
<h3 id={getTitleId()}
|
||||
className={classnames('sui-box-title', {
|
||||
'sui-lg': small
|
||||
})}>
|
||||
|
||||
{title}
|
||||
</h3>
|
||||
|
||||
{getHeaderActions()}
|
||||
</div>
|
||||
|
||||
<div className={classnames('sui-box-body', {
|
||||
'sui-content-center': small
|
||||
})}>
|
||||
{description &&
|
||||
<p className="sui-description"
|
||||
id={id + '-modal-description'}>
|
||||
{description}
|
||||
</p>}
|
||||
|
||||
{children}
|
||||
</div>
|
||||
|
||||
{footer && <div className="sui-box-footer">
|
||||
{footer}
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import React from "react";
|
||||
|
||||
export default function ProgressBar(
|
||||
{
|
||||
progress = 0,
|
||||
stateMessage = ''
|
||||
}
|
||||
) {
|
||||
progress = Math.ceil(progress);
|
||||
const progressPercentage = progress + "%";
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="sui-progress-block">
|
||||
<div className="sui-progress">
|
||||
<span className="sui-progress-icon" aria-hidden="true">
|
||||
<span className="sui-icon-loader sui-loading"/>
|
||||
</span>
|
||||
|
||||
<div className="sui-progress-text">{progressPercentage}</div>
|
||||
|
||||
<div className="sui-progress-bar">
|
||||
<span
|
||||
style={{
|
||||
transition: progress === 0 ? false : "transform 0.4s linear 0s",
|
||||
transformOrigin: "left center",
|
||||
transform: `translateX(${progress - 100}%)`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="sui-progress-state">{stateMessage}</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
176
wp-content/plugins/wp-smushit/_src/react/modules/configs.jsx
Normal file
176
wp-content/plugins/wp-smushit/_src/react/modules/configs.jsx
Normal file
@ -0,0 +1,176 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
const { __, sprintf } = wp.i18n;
|
||||
|
||||
/**
|
||||
* SUI dependencies
|
||||
*/
|
||||
import { Presets } from '@wpmudev/shared-presets';
|
||||
|
||||
export const Configs = ({ isWidget }) => {
|
||||
// TODO: Handle the html interpolation and translation better.
|
||||
const proDescription = (
|
||||
<>
|
||||
{__(
|
||||
'You can easily apply configs to multiple sites at once via ',
|
||||
'wp-smushit'
|
||||
)}
|
||||
<a
|
||||
href={window.smushReact.links.hubConfigs}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{__('the Hub.')}
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
|
||||
const closeIcon = __('Close this dialog window', 'wp-smushit'),
|
||||
cancelButton = __('Cancel', 'wp-smushit');
|
||||
|
||||
const lang = {
|
||||
title: __('Preset Configs', 'wp-smushit'),
|
||||
upload: __('Upload', 'wp-smushit'),
|
||||
save: __('Save config', 'wp-smushit'),
|
||||
loading: __('Updating the config list…', 'wp-smushit'),
|
||||
emptyNotice: __(
|
||||
'You don’t have any available config. Save preset configurations of Smush’s settings, then upload and apply them to your other sites in just a few clicks!',
|
||||
'wp-smushit'
|
||||
),
|
||||
baseDescription: __(
|
||||
'Use configs to save preset configurations of Smush’s settings, then upload and apply them to your other sites in just a few clicks!',
|
||||
'wp-smushit'
|
||||
),
|
||||
proDescription,
|
||||
syncWithHubText: __(
|
||||
'Created or updated configs via the Hub?',
|
||||
'wp-smushit'
|
||||
),
|
||||
syncWithHubButton: __('Check again', 'wp-smushit'),
|
||||
apply: __('Apply', 'wp-smushit'),
|
||||
download: __('Download', 'wp-smushit'),
|
||||
edit: __('Name and Description', 'wp-smushit'),
|
||||
delete: __('Delete', 'wp-smushit'),
|
||||
notificationDismiss: __('Dismiss notice', 'wp-smushit'),
|
||||
freeButtonLabel: __('Try The Hub', 'wp-smushit'),
|
||||
defaultRequestError: sprintf(
|
||||
/* translators: %s request status */
|
||||
__(
|
||||
'Request failed. Status: %s. Please reload the page and try again.',
|
||||
'wp-smushit'
|
||||
),
|
||||
'{status}'
|
||||
),
|
||||
uploadActionSuccessMessage: sprintf(
|
||||
/* translators: %s request status */
|
||||
__(
|
||||
'%s config has been uploaded successfully – you can now apply it to this site.',
|
||||
'wp-smushit'
|
||||
),
|
||||
'{configName}'
|
||||
),
|
||||
uploadWrongPluginErrorMessage: sprintf(
|
||||
/* translators: %s {pluginName} */
|
||||
__(
|
||||
'The uploaded file is not a %s Config. Please make sure the uploaded file is correct.',
|
||||
'wp-smushit'
|
||||
),
|
||||
'{pluginName}'
|
||||
),
|
||||
applyAction: {
|
||||
closeIcon,
|
||||
cancelButton,
|
||||
title: __('Apply Config', 'wp-smushit'),
|
||||
description: sprintf(
|
||||
/* translators: %s config name */
|
||||
__(
|
||||
'Are you sure you want to apply the %s config to this site? We recommend you have a backup available as your existing settings configuration will be overridden.',
|
||||
'wp-smushit'
|
||||
),
|
||||
'{configName}'
|
||||
),
|
||||
actionButton: __('Apply', 'wp-smushit'),
|
||||
successMessage: sprintf(
|
||||
/* translators: %s. config name */
|
||||
__('%s config has been applied successfully.', 'wp-smushit'),
|
||||
'{configName}'
|
||||
),
|
||||
},
|
||||
deleteAction: {
|
||||
closeIcon,
|
||||
cancelButton,
|
||||
title: __('Delete Configuration File', 'wp-smushit'),
|
||||
description: sprintf(
|
||||
/* translators: %s config name */
|
||||
__(
|
||||
'Are you sure you want to delete %s? You will no longer be able to apply it to this or other connected sites.',
|
||||
'wp-smushit'
|
||||
),
|
||||
'{configName}'
|
||||
),
|
||||
actionButton: __('Delete', 'wp-smushit'),
|
||||
},
|
||||
editAction: {
|
||||
closeIcon,
|
||||
cancelButton,
|
||||
nameInput: __('Config name', 'wp-smushit'),
|
||||
descriptionInput: __('Description', 'wp-smushit'),
|
||||
emptyNameError: __('The config name is required', 'wp-smushit'),
|
||||
actionButton: __('Save', 'wp-smushit'),
|
||||
editTitle: __('Rename Config', 'wp-smushit'),
|
||||
editDescription: __(
|
||||
'Change your config name to something recognizable.',
|
||||
'wp-smushit'
|
||||
),
|
||||
createTitle: __('Save Config', 'wp-smushit'),
|
||||
createDescription: __(
|
||||
'Save your current settings configuration. You’ll be able to then download and apply it to your other sites.',
|
||||
'wp-smushit'
|
||||
),
|
||||
successMessage: sprintf(
|
||||
/* translators: %s. config name */
|
||||
__('%s config created successfully.', 'wp-smushit'),
|
||||
'{configName}'
|
||||
),
|
||||
},
|
||||
settingsLabels: {
|
||||
bulk_smush: __('Bulk Smush', 'wp-smushit'),
|
||||
integrations: __('Integrations', 'wp-smushit'),
|
||||
lazy_load: __('Lazy Load', 'wp-smushit'),
|
||||
cdn: __('CDN', 'wp-smushit'),
|
||||
webp_mod: __('Local WebP', 'wp-smushit'),
|
||||
settings: __('Settings', 'wp-smushit'),
|
||||
networkwide: __('Subsite Controls', 'wp-smushit'),
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<Presets
|
||||
isWidget={isWidget}
|
||||
isPro={window.smushReact.isPro}
|
||||
isWhitelabel={window.smushReact.hideBranding}
|
||||
sourceLang={lang}
|
||||
sourceUrls={window.smushReact.links}
|
||||
requestsData={window.smushReact.requestsData}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
domReady(function () {
|
||||
const configsPageBox = document.getElementById('smush-box-configs');
|
||||
if (configsPageBox) {
|
||||
ReactDOM.render(<Configs isWidget={false} />, configsPageBox);
|
||||
}
|
||||
const configsWidgetBox = document.getElementById('smush-widget-configs');
|
||||
if (configsWidgetBox) {
|
||||
ReactDOM.render(<Configs isWidget={true} />, configsWidgetBox);
|
||||
}
|
||||
});
|
110
wp-content/plugins/wp-smushit/_src/react/modules/webp.jsx
Normal file
110
wp-content/plugins/wp-smushit/_src/react/modules/webp.jsx
Normal file
@ -0,0 +1,110 @@
|
||||
/* global ajaxurl */
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import StepsBar from '../views/webp/steps-bar';
|
||||
import StepContent from '../views/webp/step-content';
|
||||
import FreeContent from '../views/webp/free-content';
|
||||
import StepFooter from '../views/webp/step-footer';
|
||||
|
||||
export const WebpPage = ({ smushData }) => {
|
||||
const [currentStep, setCurrentStep] = React.useState(
|
||||
parseInt(smushData.startStep)
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (2 === currentStep) {
|
||||
window.SUI.suiCodeSnippet();
|
||||
}
|
||||
}, [currentStep]);
|
||||
|
||||
const [serverType, setServerType] = React.useState(
|
||||
smushData.detectedServer
|
||||
);
|
||||
const [rulesMethod, setRulesMethod] = React.useState('automatic');
|
||||
const [rulesError, setRulesError] = React.useState(false);
|
||||
|
||||
const makeRequest = (action, verb = 'GET') => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(
|
||||
verb,
|
||||
`${ajaxurl}?action=${action}&_ajax_nonce=${smushData.nonce}`,
|
||||
true
|
||||
);
|
||||
|
||||
xhr.setRequestHeader(
|
||||
'Content-type',
|
||||
'application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
xhr.onload = () => {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve(JSON.parse(xhr.response));
|
||||
} else {
|
||||
reject(xhr);
|
||||
}
|
||||
};
|
||||
xhr.onerror = () => reject(xhr);
|
||||
xhr.send();
|
||||
});
|
||||
};
|
||||
|
||||
const stepContent = smushData.isPro ? (
|
||||
<StepContent
|
||||
currentStep={currentStep}
|
||||
serverType={serverType}
|
||||
rulesMethod={rulesMethod}
|
||||
setRulesMethod={setRulesMethod}
|
||||
rulesError={rulesError}
|
||||
setServerType={setServerType}
|
||||
smushData={smushData}
|
||||
makeRequest={makeRequest}
|
||||
/>
|
||||
) : (
|
||||
<FreeContent smushData={smushData} />
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="sui-box-body sui-no-padding">
|
||||
<div className="sui-row-with-sidenav">
|
||||
<StepsBar smushData={smushData} currentStep={currentStep} />
|
||||
{stepContent}
|
||||
</div>
|
||||
</div>
|
||||
{smushData.isPro && (
|
||||
<StepFooter
|
||||
currentStep={currentStep}
|
||||
setCurrentStep={setCurrentStep}
|
||||
serverType={serverType}
|
||||
rulesMethod={rulesMethod}
|
||||
setRulesError={setRulesError}
|
||||
makeRequest={makeRequest}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
domReady(function () {
|
||||
const webpPageBox = document.getElementById('smush-box-webp-wizard');
|
||||
if (webpPageBox) {
|
||||
ReactDOM.render(
|
||||
<WebpPage smushData={window.smushReact} />,
|
||||
webpPageBox
|
||||
);
|
||||
}
|
||||
});
|
35
wp-content/plugins/wp-smushit/_src/react/utils/notices.js
Normal file
35
wp-content/plugins/wp-smushit/_src/react/utils/notices.js
Normal file
@ -0,0 +1,35 @@
|
||||
export function showSuccessNotice(id, message, dismissible = true) {
|
||||
return showNotice(id, message, 'success', dismissible);
|
||||
}
|
||||
|
||||
export function showErrorNotice(id, message, dismissible = true) {
|
||||
return showNotice(id, message, 'error', dismissible);
|
||||
}
|
||||
|
||||
export function showInfoNotice(id, message, dismissible = true) {
|
||||
return showNotice(id, message, 'info', dismissible);
|
||||
}
|
||||
|
||||
export function showWarningNotice(id, message, dismissible = true) {
|
||||
return showNotice(id, message, 'warning', dismissible);
|
||||
}
|
||||
|
||||
export function closeNotice(id) {
|
||||
SUI.closeNotice(id);
|
||||
}
|
||||
|
||||
export function showNotice(id, message, type = 'success', dismissible = true) {
|
||||
const icons = {
|
||||
error: 'warning-alert',
|
||||
info: 'info',
|
||||
warning: 'warning-alert',
|
||||
success: 'check-tick'
|
||||
};
|
||||
|
||||
SUI.closeNotice(id);
|
||||
SUI.openNotice(id, '<p>' + message + '</p>', {
|
||||
type: type,
|
||||
icon: icons[type],
|
||||
dismiss: {show: dismissible}
|
||||
});
|
||||
}
|
23
wp-content/plugins/wp-smushit/_src/react/utils/request.js
Normal file
23
wp-content/plugins/wp-smushit/_src/react/utils/request.js
Normal file
@ -0,0 +1,23 @@
|
||||
import $ from 'jquery';
|
||||
import ajaxUrl from 'ajaxUrl';
|
||||
|
||||
export function post(action, nonce, data = {}) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const request = Object.assign({}, {
|
||||
action: action,
|
||||
_ajax_nonce: nonce
|
||||
}, data);
|
||||
|
||||
$.post(ajaxUrl, request)
|
||||
.done((response) => {
|
||||
if (response.success) {
|
||||
resolve(
|
||||
response?.data
|
||||
);
|
||||
} else {
|
||||
reject(response?.data?.message);
|
||||
}
|
||||
})
|
||||
.fail(() => reject());
|
||||
});
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
export default ({ smushData }) => {
|
||||
return (
|
||||
<div className="sui-box-body">
|
||||
<div className="sui-message">
|
||||
<img
|
||||
className="sui-image"
|
||||
src={smushData.urls.freeImg}
|
||||
srcset={smushData.urls.freeImg2x + ' 2x'}
|
||||
alt={__('Smush WebP', 'wp-smushit')}
|
||||
/>
|
||||
|
||||
<div className="sui-message-content">
|
||||
<p>
|
||||
{__(
|
||||
'Fix the "Serve images in next-gen format" Google PageSpeed recommendation by setting up this feature. Serve WebP versions of your images to supported browsers, and gracefully fall back on JPEGs and PNGs for browsers that don\'t support WebP.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<ol className="sui-upsell-list">
|
||||
<li>
|
||||
<span
|
||||
className="sui-icon-check sui-sm"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{__(
|
||||
'Add or automatically apply the rules to enable Local WebP feature.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
<span
|
||||
className="sui-icon-check sui-sm"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{__(
|
||||
'Fix “Serve images in next-gen format" Google PageSpeed recommendation.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
<span
|
||||
className="sui-icon-check sui-sm"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
{__(
|
||||
'Serve WebP version of images in the browsers that support it and fall back to JPEGs and PNGs for non supported browsers.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p className="sui-margin-top">
|
||||
<a
|
||||
href={smushData.urls.upsell}
|
||||
className="sui-button sui-button-purple"
|
||||
style={{ marginRight: '30px' }}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{__('UNLOCK WEBP WITH PRO', 'wp-smushit')}
|
||||
</a>
|
||||
<a
|
||||
href={smushData.urls.webpDoc}
|
||||
style={{ color: '#8D00B1' }}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{__('Learn more', 'wp-smushit')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,441 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
const { __, sprintf } = wp.i18n;
|
||||
|
||||
export default ({
|
||||
currentStep,
|
||||
serverType,
|
||||
rulesMethod,
|
||||
setRulesMethod,
|
||||
setServerType,
|
||||
rulesError,
|
||||
smushData,
|
||||
makeRequest,
|
||||
}) => {
|
||||
const stepsHeading = {
|
||||
1: {
|
||||
title: __('Choose Server Type', 'wp-smushit'),
|
||||
description: __(
|
||||
'Choose your server type. If you don’t know this, please contact your hosting provider.',
|
||||
'wp-smushit'
|
||||
),
|
||||
},
|
||||
2: {
|
||||
title: __('Add Rules', 'wp-smushit'),
|
||||
description:
|
||||
'apache' === serverType
|
||||
? __(
|
||||
'Smush can automatically apply WebP conversion rules for Apache servers by writing to your .htaccess file. Alternatively, switch to Manual to apply these rules yourself.',
|
||||
'wp-smushit'
|
||||
)
|
||||
: __(
|
||||
'The following configurations are for NGINX servers. If you do not have access to your NGINX config files you will need to contact your hosting provider to make these changes.',
|
||||
'wp-smushit'
|
||||
),
|
||||
},
|
||||
3: {
|
||||
title: __('Finish Setup', 'wp-smushit'),
|
||||
description: __(
|
||||
'The rules have been applied successfully.',
|
||||
'wp-smushit'
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
const getTopNotice = () => {
|
||||
if (1 === currentStep && smushData.isS3Enabled) {
|
||||
return (
|
||||
<div className="sui-notice sui-notice-warning">
|
||||
<div className="sui-notice-content">
|
||||
<div className="sui-notice-message">
|
||||
<span
|
||||
className="sui-notice-icon sui-icon-info sui-md"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<p>
|
||||
{__(
|
||||
'We noticed the Amazon S3 Integration is enabled. Offloaded images will not be served in WebP format, but Smush will create local WebP copies of all images. If this is undesirable, you can quit the setup.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (2 === currentStep) {
|
||||
return (
|
||||
<div
|
||||
role="alert"
|
||||
className="sui-notice sui-notice-warning"
|
||||
aria-live="assertive"
|
||||
style={rulesError ? { display: 'block' } : {}}
|
||||
>
|
||||
{rulesError && (
|
||||
<div className="sui-notice-content">
|
||||
<div className="sui-notice-message">
|
||||
<span
|
||||
className="sui-notice-icon sui-icon-info sui-md"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: rulesError,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (smushData.isWpmudevHost) {
|
||||
const message = !smushData.isWhitelabel
|
||||
? __(
|
||||
'Since your site is hosted with WPMU DEV, we already have done the configurations steps for you. The only step for you would be to create WebP images below.',
|
||||
'wp-smushit'
|
||||
)
|
||||
: __(
|
||||
'WebP conversion is active and working well. Your hosting has automatically pre-configured the conversion for you. The only step for you would be to create WebP images below.',
|
||||
'wp-smushit'
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="sui-notice sui-notice-info">
|
||||
<div className="sui-notice-content">
|
||||
<div className="sui-notice-message">
|
||||
<span
|
||||
className="sui-notice-icon sui-icon-info sui-md"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<p>{message}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getStepContent = () => {
|
||||
if (1 === currentStep) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="sui-box-selectors">
|
||||
<ul>
|
||||
<li>
|
||||
<label
|
||||
htmlFor="smush-wizard-server-type-apache"
|
||||
className="sui-box-selector"
|
||||
>
|
||||
<input
|
||||
id="smush-wizard-server-type-apache"
|
||||
type="radio"
|
||||
value="apache"
|
||||
checked={'apache' === serverType}
|
||||
onChange={(e) =>
|
||||
setServerType(e.currentTarget.value)
|
||||
}
|
||||
/>
|
||||
<span>{__('Apache', 'wp-smushit')}</span>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<label
|
||||
htmlFor="smush-wizard-server-type-nginx"
|
||||
className="sui-box-selector"
|
||||
>
|
||||
<input
|
||||
id="smush-wizard-server-type-nginx"
|
||||
type="radio"
|
||||
value="nginx"
|
||||
checked={'nginx' === serverType}
|
||||
onChange={(e) =>
|
||||
setServerType(e.currentTarget.value)
|
||||
}
|
||||
/>
|
||||
<span>{__('NGINX', 'wp-smushit')}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="sui-notice" style={{ textAlign: 'left' }}>
|
||||
<div className="sui-notice-content">
|
||||
<div className="sui-notice-message">
|
||||
<span
|
||||
className="sui-notice-icon sui-icon-info sui-md"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
<p>
|
||||
{sprintf(
|
||||
/* translators: server type */
|
||||
__(
|
||||
"We've automatically detected your server type is %s. If this is incorrect, manually select your server type to generate the relevant rules and instructions.",
|
||||
'wp-smushit'
|
||||
),
|
||||
'nginx' === smushData.detectedServer
|
||||
? 'NGINX'
|
||||
: 'Apache / LiteSpeed'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
if (2 === currentStep) {
|
||||
if ('nginx' === serverType) {
|
||||
return (
|
||||
<div className="smush-wizard-rules-wrapper">
|
||||
<ol className="sui-description">
|
||||
<li>
|
||||
{__(
|
||||
'Insert the following in the server context of your configuration file (usually found in /etc/nginx/sites-available). “The server context” refers to the part of the configuration that starts with “server {” and ends with the matching “}”.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{__(
|
||||
'Copy the generated code found below and paste it inside your http or server blocks.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<pre
|
||||
className="sui-code-snippet"
|
||||
style={{ marginLeft: '12px' }}
|
||||
>
|
||||
{smushData.nginxRules}
|
||||
</pre>
|
||||
<ol className="sui-description" start="3">
|
||||
<li>{__('Reload NGINX.', 'wp-smushit')}</li>
|
||||
</ol>
|
||||
|
||||
<p className="sui-description">
|
||||
{__('Still having trouble?', 'wp_smushit')}{' '}
|
||||
<a
|
||||
href={smushData.urls.support}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{__('Get Support.', 'wp_smushit')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: The non-selected button isn't focusable this way. Why arrows don't workkkkkkk?
|
||||
return (
|
||||
<div className="sui-side-tabs sui-tabs">
|
||||
<div role="tablist" className="sui-tabs-menu">
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
id="smush-tab-automatic"
|
||||
className={
|
||||
'sui-tab-item' +
|
||||
('automatic' === rulesMethod ? ' active' : '')
|
||||
}
|
||||
aria-controls="smush-tab-content-automatic"
|
||||
aria-selected={'automatic' === rulesMethod}
|
||||
onClick={() => setRulesMethod('automatic')}
|
||||
tabIndex={'automatic' === rulesMethod ? '0' : '-1'}
|
||||
>
|
||||
{__('Automatic', 'wp-smushit')}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
role="tab"
|
||||
id="smush-tab-manual"
|
||||
className={
|
||||
'sui-tab-item' +
|
||||
('manual' === rulesMethod ? ' active' : '')
|
||||
}
|
||||
aria-controls="smush-tab-content-manual"
|
||||
aria-selected={'manual' === rulesMethod}
|
||||
onClick={() => setRulesMethod('manual')}
|
||||
tabIndex={'manual' === rulesMethod ? '0' : '-1'}
|
||||
>
|
||||
{__('Manual', 'wp-smushit')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="sui-tabs-content">
|
||||
<div
|
||||
role="tabpanel"
|
||||
tabIndex="0"
|
||||
id="smush-tab-content-automatic"
|
||||
className={
|
||||
'sui-tab-content' +
|
||||
('automatic' === rulesMethod ? ' active' : '')
|
||||
}
|
||||
aria-labelledby="smush-tab-automatic"
|
||||
hidden={'automatic' !== rulesMethod}
|
||||
>
|
||||
<p
|
||||
className="sui-description"
|
||||
style={{ marginTop: '30px' }}
|
||||
>
|
||||
{__(
|
||||
'Please note: Some servers have both Apache and NGINX software which may not begin serving WebP images after applying the .htaccess rules. If errors occur after applying the rules, we recommend adding NGINX rules manually.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
role="tabpanel"
|
||||
tabIndex="0"
|
||||
id="smush-tab-content-manual"
|
||||
className={
|
||||
'sui-tab-content' +
|
||||
('manual' === rulesMethod ? ' active' : '')
|
||||
}
|
||||
aria-labelledby="smush-tab-manual"
|
||||
hidden={'manual' !== rulesMethod}
|
||||
>
|
||||
<p className="sui-description">
|
||||
{__(
|
||||
'If you are unable to get the automated method working, follow these steps:',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className="smush-wizard-rules-wrapper">
|
||||
<ol className="sui-description">
|
||||
<li>
|
||||
{__(
|
||||
'Copy the generated code below and paste it at the top of your .htaccess file (before any existing code) in the root directory.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<pre
|
||||
className="sui-code-snippet"
|
||||
style={{ marginLeft: '12px' }}
|
||||
>
|
||||
{smushData.apacheRules}
|
||||
</pre>
|
||||
<ol className="sui-description" start="2">
|
||||
<li>
|
||||
{__(
|
||||
"Next, click Check Status button below to see if it's working.",
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h5
|
||||
className="sui-settings-label"
|
||||
style={{
|
||||
marginTop: '30px',
|
||||
fontSize: '13px',
|
||||
color: '#333333',
|
||||
}}
|
||||
>
|
||||
{__('Troubleshooting', 'wp-smushit')}
|
||||
</h5>
|
||||
|
||||
<p className="sui-description">
|
||||
{__(
|
||||
'If .htaccess does not work, and you have access to vhosts.conf or httpd.conf, try this:',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<ol className="sui-description">
|
||||
<li>
|
||||
{__(
|
||||
'Look for your site in the file and find the line that starts with <Directory> - add the code above that line and into that section and save the file.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{__('Reload Apache.', 'wp-smushit')}
|
||||
</li>
|
||||
<li>
|
||||
{__(
|
||||
"If you don't know where those files are, or you aren't able to reload Apache, you would need to consult with your hosting provider or a system administrator who has access to change the configuration of your server.",
|
||||
'wp-smushit'
|
||||
)}
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p className="sui-description">
|
||||
{__('Still having trouble?', 'wp_smushit')}{' '}
|
||||
<a
|
||||
href={smushData.urls.support}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{__('Get Support.', 'wp_smushit')}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const hideWizard = (e) => {
|
||||
e.preventDefault();
|
||||
makeRequest('smush_toggle_webp_wizard').then(() => {
|
||||
location.href = smushData.urls.bulkPage;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<p style={{ marginBottom: 0 }}><b>{__('Convert Images to WebP', 'wp-smushit')}</b></p>
|
||||
<p className="sui-description" dangerouslySetInnerHTML={ { __html: smushData.thirdStepMsg } } />
|
||||
{!smushData.isMultisite && (
|
||||
<p>
|
||||
<a href={smushData.urls.bulkPage} onClick={hideWizard}>
|
||||
{__('Convert now', 'wp-smushit')}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const stepIndicatorText = sprintf(
|
||||
/* translators: currentStep/totalSteps indicator */
|
||||
__('Step %s', 'wp-smushit'),
|
||||
currentStep + '/3'
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`smush-wizard-steps-content-wrapper smush-wizard-step-${currentStep}`}
|
||||
>
|
||||
{getTopNotice()}
|
||||
<div className="smush-wizard-steps-content">
|
||||
<span className="smush-step-indicator">
|
||||
{stepIndicatorText}
|
||||
</span>
|
||||
<h2>{stepsHeading[currentStep].title}</h2>
|
||||
<p className="sui-description">
|
||||
{stepsHeading[currentStep].description}
|
||||
</p>
|
||||
{getStepContent()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
export default ({
|
||||
currentStep,
|
||||
setCurrentStep,
|
||||
serverType,
|
||||
rulesMethod,
|
||||
setRulesError,
|
||||
makeRequest,
|
||||
}) => {
|
||||
const genericRequestError = __(
|
||||
'Something went wrong with the request.',
|
||||
'wp-smushit'
|
||||
);
|
||||
|
||||
const checkStatus = () => {
|
||||
setRulesError(false);
|
||||
|
||||
makeRequest('smush_webp_get_status')
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
setCurrentStep(currentStep + 1);
|
||||
} else {
|
||||
setRulesError(res.data);
|
||||
}
|
||||
})
|
||||
.catch(() => setRulesError(genericRequestError));
|
||||
};
|
||||
|
||||
const applyRules = () => {
|
||||
setRulesError(false);
|
||||
|
||||
makeRequest('smush_webp_apply_htaccess_rules')
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
return checkStatus();
|
||||
}
|
||||
|
||||
setRulesError(res.data);
|
||||
})
|
||||
.catch(() => setRulesError(genericRequestError));
|
||||
};
|
||||
|
||||
const hideWizard = (e) => {
|
||||
e.currentTarget.classList.add(
|
||||
'sui-button-onload',
|
||||
'sui-button-onload-text'
|
||||
);
|
||||
makeRequest('smush_toggle_webp_wizard').then(() => location.reload());
|
||||
};
|
||||
|
||||
// Markup stuff.
|
||||
let buttonsLeft;
|
||||
|
||||
const quitButton = (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-ghost"
|
||||
onClick={hideWizard}
|
||||
>
|
||||
<span className="sui-loading-text">
|
||||
<span className="sui-icon-logout" aria-hidden="true"></span>
|
||||
<span className="sui-hidden-xs">
|
||||
{__('Quit setup', 'wp-smushit')}
|
||||
</span>
|
||||
<span className="sui-hidden-sm sui-hidden-md sui-hidden-lg">
|
||||
{__('Quit', 'wp-smushit')}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span
|
||||
className="sui-icon-loader sui-loading"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
</button>
|
||||
);
|
||||
|
||||
if (1 !== currentStep) {
|
||||
buttonsLeft = (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-compound sui-button-ghost"
|
||||
onClick={() => setCurrentStep(currentStep - 1)}
|
||||
>
|
||||
<span className="sui-compound-desktop" aria-hidden="true">
|
||||
<span className="sui-icon-arrow-left"></span>
|
||||
{__('Previous', 'wp-smushit')}
|
||||
</span>
|
||||
|
||||
<span className="sui-compound-mobile" aria-hidden="true">
|
||||
<span className="sui-icon-arrow-left"></span>
|
||||
</span>
|
||||
|
||||
<span className="sui-screen-reader-text">
|
||||
{__('Previous', 'wp-smushit')}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
const getButtonsRight = () => {
|
||||
if (1 === currentStep) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-blue sui-button-icon-right"
|
||||
onClick={() => setCurrentStep(currentStep + 1)}
|
||||
>
|
||||
{__('Next', 'wp-smushit')}
|
||||
<span
|
||||
className="sui-icon-arrow-right"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
if (2 === currentStep) {
|
||||
if ('apache' === serverType && 'automatic' === rulesMethod) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-blue"
|
||||
onClick={applyRules}
|
||||
>
|
||||
{__('Apply rules', 'wp-smushit')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-blue"
|
||||
onClick={checkStatus}
|
||||
>
|
||||
{__('Check status', 'wp-smushit')}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="sui-button sui-button-blue"
|
||||
onClick={hideWizard}
|
||||
>
|
||||
<span className="sui-button-text-default">
|
||||
{__('Finish', 'wp-smushit')}
|
||||
</span>
|
||||
|
||||
<span className="sui-button-text-onload">
|
||||
<span
|
||||
className="sui-icon-loader sui-loading"
|
||||
aria-hidden="true"
|
||||
></span>
|
||||
{__('Finishing setup…', 'wp-smushit')}
|
||||
</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="sui-box-footer">
|
||||
<div className="sui-actions-left">
|
||||
{quitButton}
|
||||
{buttonsLeft}
|
||||
</div>
|
||||
<div className="sui-actions-right">{getButtonsRight()}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import React from 'react';
|
||||
|
||||
/**
|
||||
* WordPress dependencies
|
||||
*/
|
||||
const { __ } = wp.i18n;
|
||||
|
||||
export default ({ currentStep, smushData }) => {
|
||||
const getStepClass = (step) => {
|
||||
const stepClass = 'smush-wizard-bar-step';
|
||||
|
||||
if (!smushData.isPro) {
|
||||
return stepClass + ' disabled';
|
||||
}
|
||||
|
||||
if (step > currentStep) {
|
||||
return stepClass;
|
||||
}
|
||||
|
||||
return (
|
||||
stepClass +
|
||||
(step === currentStep ? ' current' : ' sui-tooltip done')
|
||||
);
|
||||
};
|
||||
|
||||
const getStepNumber = (step) => {
|
||||
return currentStep > step ? (
|
||||
<span className="sui-icon-check" aria-hidden="true"></span>
|
||||
) : (
|
||||
step
|
||||
);
|
||||
};
|
||||
|
||||
const steps = [
|
||||
{ number: 1, title: __('Server Type', 'wp-smushit') },
|
||||
{ number: 2, title: __('Add Rules', 'wp-smushit') },
|
||||
{ number: 3, title: __('Finish Setup', 'wp-smushit') },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="sui-sidenav">
|
||||
<span className="smush-wizard-bar-subtitle">
|
||||
{__('Setup', 'wp-smushit')}
|
||||
</span>
|
||||
<div className="smush-sidenav-title">
|
||||
<h4>{__('Local WebP', 'wp-smushit')}</h4>
|
||||
{!smushData.isPro && (
|
||||
<span className="sui-tag sui-tag-pro">
|
||||
{__('Pro', 'wp-smushit')}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="smush-wizard-steps-container">
|
||||
<svg
|
||||
className="smush-svg-mobile"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<line
|
||||
x1="0"
|
||||
x2="50%"
|
||||
stroke={1 !== currentStep ? '#1ABC9C' : '#E6E6E6'}
|
||||
/>
|
||||
<line
|
||||
x1="50%"
|
||||
x2="100%"
|
||||
stroke={3 === currentStep ? '#1ABC9C' : '#E6E6E6'}
|
||||
/>
|
||||
</svg>
|
||||
<ul>
|
||||
{steps.map((step) => (
|
||||
<React.Fragment key={step.number}>
|
||||
<li
|
||||
className={getStepClass(step.number)}
|
||||
data-tooltip={__(
|
||||
'This stage is already completed.',
|
||||
'wp-smushit'
|
||||
)}
|
||||
>
|
||||
<div className="smush-wizard-bar-step-number">
|
||||
{getStepNumber(step.number)}
|
||||
</div>
|
||||
{step.title}
|
||||
</li>
|
||||
{3 !== step.number && (
|
||||
<svg
|
||||
data={step.number}
|
||||
data2={currentStep}
|
||||
className="smush-svg-desktop"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<line
|
||||
y1="0"
|
||||
y2="40px"
|
||||
stroke={
|
||||
step.number < currentStep
|
||||
? '#1ABC9C'
|
||||
: '#E6E6E6'
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,50 @@
|
||||
@include body-class(true) {
|
||||
&.sui-color-accessible {
|
||||
.smush-final-log .smush-bulk-error-row {
|
||||
box-shadow: inset 2px 0 0 0 $accessible-dark;
|
||||
.smush-bulk-image-data:before {
|
||||
color: $accessible-dark;
|
||||
}
|
||||
}
|
||||
// Bulk Smush Fancy Tree
|
||||
ul.fancytree-container {
|
||||
.fancytree-selected {
|
||||
background-color: #F8F8F8;
|
||||
span.fancytree-checkbox {
|
||||
border: 1px solid $accessible-dark;
|
||||
background-color: $accessible-dark;
|
||||
}
|
||||
}
|
||||
span.fancytree-expander:before,
|
||||
span.fancytree-icon:before,
|
||||
span.fancytree-title {
|
||||
color: $accessible-dark;
|
||||
}
|
||||
}
|
||||
// CDN
|
||||
.smush-filename-extension {
|
||||
background-color: $accessible-dark;
|
||||
}
|
||||
// Check images button.
|
||||
.sui-button {
|
||||
&.smush-button-check-success:before {
|
||||
color: $accessible-light;
|
||||
}
|
||||
}
|
||||
// Smush submit note.
|
||||
.smush-submit-note {
|
||||
color: $accessible-dark;
|
||||
}
|
||||
|
||||
// Hightlight lazyload spinner.
|
||||
.sui-lazyload .sui-box-selector [name="animation[spinner-icon]"]:checked+span {
|
||||
background-color: rgba(220,220,222, 0.7)!important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||
.sui-wrap .sui-toggle-slider {
|
||||
-ms-high-contrast-adjust: none;
|
||||
}
|
||||
}
|
59
wp-content/plugins/wp-smushit/_src/scss/app.scss
Normal file
59
wp-content/plugins/wp-smushit/_src/scss/app.scss
Normal file
@ -0,0 +1,59 @@
|
||||
// This needs to be here.
|
||||
@import "modules/variables";
|
||||
|
||||
// Share UI styles
|
||||
@import "~@wpmudev/shared-ui/scss/functions";
|
||||
@import "~@wpmudev/shared-ui/scss/colors";
|
||||
@import "~@wpmudev/shared-ui/scss/variables";
|
||||
$google-fonts-url: 'https://fonts.bunny.net/css?family=Roboto:400,500,700';
|
||||
@import "~@wpmudev/shared-ui/scss/mixins";
|
||||
@import "~@wpmudev/shared-ui/scss/accessibility";
|
||||
@import "~@wpmudev/shared-ui/scss/animations";
|
||||
@import "~@wpmudev/shared-ui/scss/typography";
|
||||
@import "~@wpmudev/shared-ui/scss/icons";
|
||||
@import "~@wpmudev/shared-ui/scss/buttons";
|
||||
@import "~@wpmudev/shared-ui/scss/toggles";
|
||||
@import "~@wpmudev/shared-ui/scss/boxes";
|
||||
@import "~@wpmudev/shared-ui/scss/box-settings";
|
||||
@import "~@wpmudev/shared-ui/scss/layout";
|
||||
@import "~@wpmudev/shared-ui/scss/notifications";
|
||||
@import "~@wpmudev/shared-ui/scss/header";
|
||||
@import "~@wpmudev/shared-ui/scss/summary";
|
||||
@import "~@wpmudev/shared-ui/scss/list";
|
||||
@import "~@wpmudev/shared-ui/scss/tooltips";
|
||||
@import "~@wpmudev/shared-ui/scss/select2";
|
||||
@import "~@wpmudev/shared-ui/scss/tags";
|
||||
@import "~@wpmudev/shared-ui/scss/forms";
|
||||
@import "~@wpmudev/shared-ui/scss/radio-checkbox";
|
||||
@import "~@wpmudev/shared-ui/scss/tabs";
|
||||
@import "~@wpmudev/shared-ui/scss/sidenav";
|
||||
@import "~@wpmudev/shared-ui/scss/dropdowns";
|
||||
@import "~@wpmudev/shared-ui/scss/scores";
|
||||
@import "~@wpmudev/shared-ui/scss/footer";
|
||||
@import "~@wpmudev/shared-ui/scss/progress-bars";
|
||||
@import "~@wpmudev/shared-ui/scss/modals";
|
||||
@import "~@wpmudev/shared-ui/scss/utility";
|
||||
@import "~@wpmudev/shared-ui/scss/wp-admin-notices";
|
||||
@import "~@wpmudev/shared-ui/scss/tables";
|
||||
@import "~@wpmudev/shared-ui/scss/accordions";
|
||||
// Used on lazy loading page (since 3.2.2).
|
||||
@import "~@wpmudev/shared-ui/scss/box-selectors";
|
||||
@import "~@wpmudev/shared-ui/scss/upload";
|
||||
@import "~@wpmudev/shared-ui/scss/_colorpickers.scss";
|
||||
// Upgrade page (since 3.2.3).
|
||||
@import "~@wpmudev/shared-ui/scss/upgrade-page";
|
||||
@import "~@wpmudev/shared-ui/scss/reviews";
|
||||
// Used on WebP page (since 3.8.0).
|
||||
@import "~@wpmudev/shared-ui/scss/_code-snippet.scss";
|
||||
// Upsells (since 3.9.1).
|
||||
@import "~@wpmudev/shared-ui/scss/upsells";
|
||||
|
||||
// App styles
|
||||
@import "modules/admin";
|
||||
@import "modules/directory-smush";
|
||||
@import "modules/cdn";
|
||||
@import "modules/webp";
|
||||
|
||||
// SUI Color Accessibility
|
||||
@import "~@wpmudev/shared-ui/scss/color-accessibility";
|
||||
@import "accessibility/color-accessibility";
|
597
wp-content/plugins/wp-smushit/_src/scss/common.scss
Normal file
597
wp-content/plugins/wp-smushit/_src/scss/common.scss
Normal file
@ -0,0 +1,597 @@
|
||||
/**
|
||||
* Common styles that are used on all the WP pages in the backend
|
||||
*/
|
||||
@import "modules/media";
|
||||
|
||||
.sui-wrap .smush-upsell-link,
|
||||
.sui-wrap a.smush-upsell-link {
|
||||
color: $purple;
|
||||
> span:before {
|
||||
color: $purple;
|
||||
}
|
||||
&:hover:not(.sui-button),
|
||||
&:focus:not(.sui-button),
|
||||
&:active:not(.sui-button) {
|
||||
color: #64007e;
|
||||
> span:before {
|
||||
color: #64007e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Media details (grid layout)
|
||||
* @since 3.4.0
|
||||
*/
|
||||
.attachment-info .smush-stats .value {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.smush-status {
|
||||
margin: 0 0 10px;
|
||||
flex-basis: 100%;
|
||||
font-size: 12px;
|
||||
line-height: 1.33333;
|
||||
}
|
||||
|
||||
.smush-status-links {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
span.sui-tooltip {
|
||||
float: none;
|
||||
}
|
||||
|
||||
a {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a:first-of-type {
|
||||
margin-left: 0;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-info .smush-status-links,
|
||||
.column-smushit .smush-status-links {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.column-smushit .smush-status-links > a {
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.wp-smush-progress {
|
||||
padding-left: 25px;
|
||||
margin: 0;
|
||||
background-size: 17px 17px;
|
||||
visibility: visible;
|
||||
vertical-align: initial !important; /* prevent from jumping on a line */
|
||||
display: inline;
|
||||
color: #32373c;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
// Fix grid view links.
|
||||
.attachment-details .setting span.wp-smush-progress {
|
||||
width: auto;
|
||||
line-height: 0;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/** Settings Page **/
|
||||
.smush-status.fail {
|
||||
color: #dd3d36;
|
||||
}
|
||||
|
||||
.smush-status.success {
|
||||
color: #0074a2;
|
||||
}
|
||||
|
||||
.smush-status.error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#wpbody-content .wp-smush-error {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.wp-smush-action[disabled] {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
#post-body-content .smush-status {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.attachment-info .wp-smush-error-message {
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
||||
.smush-stats-wrapper .row {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.smush-stats-wrapper .row:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.smush-stats-wrapper td, .smush-stats-wrapper th {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.smush-skipped .dashicons-editor-help {
|
||||
margin-top: -2px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.smush-skipped {
|
||||
a:focus { box-shadow: 0 0 black; }
|
||||
.sui-tag.sui-tag-purple {
|
||||
min-height: 18px;
|
||||
padding: 2px 10px;
|
||||
font-size: 10px;
|
||||
line-height: 12px;
|
||||
font-weight: 700;
|
||||
background-color: #8d00b1;
|
||||
color: #fff;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
/** Help Tip **/
|
||||
.ui-tooltip-content {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/** All Smushed **/
|
||||
.wp-smush-notice {
|
||||
background-color: #D1F1EA;
|
||||
border-radius: 5px;
|
||||
color: #333333;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
margin-bottom: 30px;
|
||||
padding: 15px 30px;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
|
||||
div.smush-notice-cta a.smush-notice-act.button-primary {
|
||||
padding: 3px 23px;
|
||||
background-color: #00B0DB;
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
text-shadow: none;
|
||||
font-weight: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
&:hover {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
a.wp-smush-resize-enable:hover,
|
||||
a.wp-smush-lossy-enable:hover {
|
||||
color: #0A9BD6;
|
||||
}
|
||||
|
||||
.wp-smush-bulk-wrapper {
|
||||
#wp-smush-bulk-image-count {
|
||||
color: #333333;
|
||||
font-size: 28px;
|
||||
line-height: 40px;
|
||||
letter-spacing: -0.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
#wp-smush-bulk-image-count-description {
|
||||
color: #333333;
|
||||
font-size: 13px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sui-tooltip,
|
||||
.sui-tooltip > .sui-icon-info {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
/** Image Remaining **/
|
||||
div.wp-smush-remaining,
|
||||
div.wp-smush-dir-limit,
|
||||
div.smush-s3-setup-message {
|
||||
background-color: #FFF5D5;
|
||||
border: none;
|
||||
color: #333333;
|
||||
line-height: 30px;
|
||||
font-size: 15px;
|
||||
letter-spacing: -0.015em;
|
||||
}
|
||||
|
||||
div.smush-s3-setup-message {
|
||||
background-color: #DFF6FA;
|
||||
}
|
||||
|
||||
div.wp-smush-dir-limit {
|
||||
background-color: #dff6fa;
|
||||
}
|
||||
|
||||
.wp-smush-resmush-wrap .wp-smush-remaining {
|
||||
padding: 10px 50px;
|
||||
}
|
||||
|
||||
.wp-smush-count {
|
||||
color: #888888;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/** Stats Container **/
|
||||
|
||||
a.wp-smush-lossy-enable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/** Re Smush **/
|
||||
.wp-smush-settings-changed {
|
||||
background: #dff6fa;
|
||||
border-radius: 5px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.compat-item .compat-field-wp_smush {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.manage-column.column-smushit {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
.smushit [tooltip],
|
||||
label.setting.smush-stats [tooltip],
|
||||
.compat-field-wp_smush [tooltip] {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.smushit [tooltip]:before,
|
||||
label.setting.smush-stats [tooltip]:before,
|
||||
.compat-field-wp_smush [tooltip]:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border: 5px solid transparent;
|
||||
border-top-color: #0B2F3F;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
margin-bottom: -5px;
|
||||
opacity: 0;
|
||||
z-index: -1;
|
||||
transition: margin .2s, opacity .2s, z-index .2s linear .2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.smushit [tooltip]:after,
|
||||
label.setting.smush-stats [tooltip]:after,
|
||||
.compat-field-wp_smush [tooltip]:after {
|
||||
background: #0B2F3F;
|
||||
border-radius: 4px;
|
||||
bottom: 100%;
|
||||
color: #FFF;
|
||||
content: attr(tooltip);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
left: 50%;
|
||||
line-height: 20px;
|
||||
margin-left: -100px;
|
||||
margin-bottom: 5px;
|
||||
opacity: 0;
|
||||
padding: 5px;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
width: 180px;
|
||||
text-align: center;
|
||||
transition: margin .2s, opacity .2s, z-index .2s linear .2s;
|
||||
white-space: pre-wrap;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.smushit .smush-skipped [tooltip]:before,
|
||||
label.setting.smush-stats .smush-skipped [tooltip]:before,
|
||||
.compat-field-wp_smush .smush-skipped [tooltip]:before {
|
||||
border-top-color: transparent;
|
||||
border-left-color: #0B2F3F;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.smushit .smush-skipped [tooltip]:after,
|
||||
label.setting.smush-stats .smush-skipped [tooltip]:after,
|
||||
.compat-field-wp_smush .smush-skipped [tooltip]:after {
|
||||
margin-left: 0;
|
||||
left: -195px;
|
||||
top: -35px;
|
||||
bottom: inherit;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
label.setting.smush-stats .smush-skipped [tooltip]:after {
|
||||
top: -98px;
|
||||
}
|
||||
|
||||
div.media-sidebar label.setting.smush-stats .smush-skipped [tooltip]:after {
|
||||
left: -188px;
|
||||
padding-left: 10px;
|
||||
width: 170px;
|
||||
}
|
||||
|
||||
div.media-sidebar label.setting.smush-stats .smush-skipped [tooltip]:before {
|
||||
margin-left: -3px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-s:after,
|
||||
label.setting.smush-stats [tooltip].tooltip-s:after,
|
||||
.compat-field-wp_smush [tooltip].tooltip-s:after {
|
||||
width: 150px;
|
||||
margin-left: -75px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-l:after,
|
||||
label.setting.smush-stats [tooltip].tooltip-l:after,
|
||||
.compat-field-wp_smush [tooltip].tooltip-l:after {
|
||||
width: 280px;
|
||||
margin-left: -140px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-right:after {
|
||||
margin-left: -180px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-s.tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-s.tooltip-right:after {
|
||||
margin-left: -130px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-l.tooltip-right:after, .compat-field-wp_smush [tooltip].tooltip-l.tooltip-right:after {
|
||||
margin-left: -260px;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-bottom:before, .compat-field-wp_smush [tooltip].tooltip-bottom:before {
|
||||
border-color: transparent;
|
||||
border-bottom-color: #0B2F3F;
|
||||
top: 100%;
|
||||
bottom: auto;
|
||||
margin-top: -5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.smushit [tooltip].tooltip-bottom:after, .compat-field-wp_smush [tooltip].tooltip-bottom:after {
|
||||
bottom: auto;
|
||||
top: 100%;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.smushit [tooltip]:hover:before,
|
||||
label.setting.smush-stats [tooltip]:hover:before,
|
||||
.compat-field-wp_smush [tooltip]:hover:before {
|
||||
z-index: 1;
|
||||
margin-bottom: 0;
|
||||
opacity: 1;
|
||||
transition: margin .2s, opacity .2s;
|
||||
}
|
||||
|
||||
.smushit [tooltip]:hover:after,
|
||||
label.setting.smush-stats [tooltip]:hover:after,
|
||||
.compat-field-wp_smush [tooltip]:hover:after {
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
margin-bottom: 10px;
|
||||
transition: margin .2s, opacity .2s;
|
||||
}
|
||||
|
||||
.smushit .disabled[tooltip]:before,
|
||||
.smushit .disabled[tooltip]:after,
|
||||
label.setting.smush-stats .disabled[tooltip]:before,
|
||||
label.setting.smush-stats .disabled[tooltip]:after,
|
||||
.compat-field-wp_smush .disabled[tooltip]:before,
|
||||
.compat-field-wp_smush .disabled[tooltip]:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** Image List **/
|
||||
div.wp-smush-scan-result {
|
||||
background: white;
|
||||
|
||||
div.wp-smush-notice {
|
||||
margin-top: 14px;
|
||||
padding: 15px 30px;
|
||||
}
|
||||
|
||||
div.content {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
div.wp-smush-info.notice {
|
||||
font-size: 15px;
|
||||
letter-spacing: -0.015em;
|
||||
margin: 0 0 30px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/** Media Queries **/
|
||||
|
||||
@media screen and (max-width: 1024px) and (min-width: 800px) {
|
||||
/** Stats Section **/
|
||||
.smush-stats-wrapper h3 {
|
||||
padding: 6px 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Media Queries for resolution below 782px **/
|
||||
@media only screen and (max-width: 800px) {
|
||||
.dev-box.bulk-smush-wrapper.wp-smush-container {
|
||||
padding: 20px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS styles used Admin notice
|
||||
*/
|
||||
.smush-notice.notice {
|
||||
padding: 0;
|
||||
margin: 5px 0 10px;
|
||||
border: 1px solid #E5E5E5;
|
||||
background: #FFF;
|
||||
overflow: hidden;
|
||||
-webkit-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
-webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
|
||||
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 80px;
|
||||
display: table; /* The magic ingredient! */
|
||||
font: 13px "Roboto", sans-serif;
|
||||
}
|
||||
|
||||
.smush-notice.notice.loading:before {
|
||||
content: attr(data-message);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
z-index: 5;
|
||||
text-align: center;
|
||||
line-height: 80px;
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.smush-notice > div {
|
||||
display: table-cell; /* The magic ingredient! */
|
||||
vertical-align: middle;
|
||||
cursor: default;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.smush-notice.notice.loading > div {
|
||||
-webkit-filter: blur(2px);
|
||||
-moz-filter: blur(2px);
|
||||
-o-filter: blur(2px);
|
||||
-ms-filter: blur(2px);
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.smush-notice-logo {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.smush-notice-message {
|
||||
color: #23282D;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
line-height: 20px;
|
||||
padding: 20px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.smush-notice-cta {
|
||||
background: #F8F8F8;
|
||||
padding: 0 30px;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wp-core-ui .smush-notice-cta button,
|
||||
.wp-core-ui .smush-notice-cta .button-primary:active {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wp-core-ui .smush-notice-cta input[type="email"] {
|
||||
vertical-align: middle;
|
||||
line-height: 20px;
|
||||
margin: 0;
|
||||
min-width: 50px;
|
||||
max-width: 320px;
|
||||
text-align: center;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upsell lists.
|
||||
* @since 3.9.1
|
||||
*/
|
||||
#smush-box-cdn-upsell,
|
||||
#smush-box-webp-wizard {
|
||||
.sui-upsell-list {
|
||||
max-width: 525px;
|
||||
text-align: left;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only all and (max-width: 1000px) {
|
||||
.smush-notice.notice {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.smush-notice > .smush-notice-logo {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
height: 80px;
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.smush-notice > .smush-notice-message {
|
||||
width: auto;
|
||||
display: block;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.smush-notice > .smush-notice-cta {
|
||||
display: block;
|
||||
border-top: 1px solid #E5E5E5;
|
||||
border-left: 0;
|
||||
text-align: center;
|
||||
white-space: normal;
|
||||
line-height: 30px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.wp-core-ui .smush-notice > .smush-notice-cta > input[type="email"],
|
||||
.smush-notice > .smush-notice-cta > button {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only all and (max-width: 500px) {
|
||||
.wp-core-ui .smush-notice > .smush-notice-cta > input[type="email"],
|
||||
.smush-notice > .smush-notice-cta > button {
|
||||
display: block;
|
||||
width: 100% !important;
|
||||
max-width: none;
|
||||
margin-bottom: 4px;
|
||||
font-size: 16px;
|
||||
height: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
.smush-dismissible-notice {
|
||||
position: relative;
|
||||
}
|
1375
wp-content/plugins/wp-smushit/_src/scss/modules/_admin.scss
Normal file
1375
wp-content/plugins/wp-smushit/_src/scss/modules/_admin.scss
Normal file
File diff suppressed because it is too large
Load Diff
72
wp-content/plugins/wp-smushit/_src/scss/modules/_cdn.scss
Normal file
72
wp-content/plugins/wp-smushit/_src/scss/modules/_cdn.scss
Normal file
@ -0,0 +1,72 @@
|
||||
@import "variables";
|
||||
|
||||
/**
|
||||
* CDN styles
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
@include body-class {
|
||||
|
||||
.sui-wrap {
|
||||
|
||||
.sui-box-settings-row .sui-box-settings-col-1 {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&.wrap-smush-cdn {
|
||||
.sui-block-content-center p {
|
||||
max-width: 600px;
|
||||
margin: 20px auto 30px;
|
||||
}
|
||||
.sui-box-header .sui-actions-right .sui-icon-info{
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
top: 1.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.sui-cdn {
|
||||
form p:first-of-type {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
.wp-smush-stats {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 0;
|
||||
|
||||
.sui-tooltip {
|
||||
line-height: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filename Extensions Icons */
|
||||
.smush-filename-extension {
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
font-size: 9px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
line-height: 43px;
|
||||
height: 30px;
|
||||
margin: 0 5px 0 0;
|
||||
width: 30px;
|
||||
|
||||
&.smush-extension-jpeg,
|
||||
&.smush-extension-jpg { background-color: #F7E100; }
|
||||
&.smush-extension-png { background-color: #FFB694; }
|
||||
&.smush-extension-gif { background-color: #72D5D4; }
|
||||
&.smush-extension-webp { background-color: #72ADD5; }
|
||||
&.smush-extension-svg { background-color: #88D572; }
|
||||
&.smush-extension-iframe {
|
||||
background-color: #8772D5;
|
||||
font-size: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,338 @@
|
||||
/* ****************************************************************************
|
||||
* MODULE: Directory Smush styles.
|
||||
*/
|
||||
|
||||
@include body-class {
|
||||
|
||||
.wp-smush-progress-dialog,
|
||||
.wp-smush-list-dialog {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sui-directory.sui-message {
|
||||
text-align: left;
|
||||
|
||||
.sui-message-content {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.sui-directory .smush-final-log {
|
||||
margin-top: 30px;
|
||||
|
||||
.sui-description {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
ul.fancytree-container {
|
||||
color: #666;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
letter-spacing: -0.25px;
|
||||
line-height: 40px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
outline: 0 solid transparent;
|
||||
min-height: 0%;
|
||||
position: relative;
|
||||
|
||||
ul {
|
||||
padding: 0 0 0 16px;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Expander icon
|
||||
*
|
||||
* Note: IE6 doesn't correctly evaluate multiples class names,
|
||||
* so we create combined class names that can be used in the CSS.
|
||||
*
|
||||
* Prefix: fancytree-exp-
|
||||
* 1st character: 'e': expanded, 'c': collapsed, 'n': no children
|
||||
* 2nd character (optional): 'd': lazy (Delayed)
|
||||
* 3rd character (optional): 'l': Last sibling
|
||||
*----------------------------------------------------------------------------*/
|
||||
span.fancytree-expander {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
margin-left: 13px;
|
||||
width: 15px;
|
||||
|
||||
&:before {
|
||||
font-family: wpmudev-plugin-icons, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
.fancytree-exp-c span.fancytree-expander,
|
||||
.fancytree-exp-cd:not(.fancytree-unselectable) span.fancytree-expander,
|
||||
.fancytree-exp-cf:not(.fancytree-unselectable) span.fancytree-expander {
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
// --- End nodes (use connectors instead of expanders)
|
||||
|
||||
.fancytree-expanded.fancytree-exp-n span.fancytree-expander,
|
||||
.fancytree-expanded.fancytree-exp-nl span.fancytree-expander {
|
||||
width: 13px;
|
||||
display: inline-block;
|
||||
|
||||
&:before {
|
||||
background-image: none;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.fancytree-exp-n span.fancytree-expander,
|
||||
.fancytree-exp-nl span.fancytree-expander {
|
||||
width: 12px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fancytree-exp-nl span.fancytree-expander:before {
|
||||
content: "\131";
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
span.fancytree-ico-c span.fancytree-expander:before {
|
||||
content: '';
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
// --- Collapsed
|
||||
|
||||
.fancytree-exp-c span.fancytree-expander:before,
|
||||
.fancytree-exp-cl span.fancytree-expander:before,
|
||||
.fancytree-exp-cd span.fancytree-expander:before,
|
||||
.fancytree-exp-cdl span.fancytree-expander:before,
|
||||
.fancytree-exp-e span.fancytree-expander:before,
|
||||
.fancytree-exp-ed span.fancytree-expander:before,
|
||||
.fancytree-exp-el span.fancytree-expander:before,
|
||||
.fancytree-exp-edl span.fancytree-expander:before {
|
||||
color: #888888;
|
||||
content: "\2DC";
|
||||
}
|
||||
|
||||
// --- Expanded
|
||||
|
||||
.fancytree-exp-e span.fancytree-expander:before,
|
||||
.fancytree-exp-ed span.fancytree-expander:before,
|
||||
.fancytree-exp-el span.fancytree-expander:before,
|
||||
.fancytree-exp-edl span.fancytree-expander:before {
|
||||
content: "\131";
|
||||
}
|
||||
|
||||
// --- Unselectable
|
||||
|
||||
.fancytree-unselectable span.fancytree-expander:before {
|
||||
content: "9";
|
||||
}
|
||||
|
||||
/* Fade out expanders, when container is not hovered or active */
|
||||
.fancytree-fade-expander {
|
||||
span.fancytree-expander:before {
|
||||
transition: opacity 1.5s;
|
||||
opacity: 0;
|
||||
}
|
||||
&:hover span.fancytree-expander:before,
|
||||
&.fancytree-treefocus span.fancytree-expander:before,
|
||||
.fancytree-treefocus span.fancytree-expander:before,
|
||||
[class*='fancytree-statusnode-'] span.fancytree-expander:before {
|
||||
transition: opacity 0.6s;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Checkbox icon
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
span.fancytree-checkbox {
|
||||
margin-right: 5px;
|
||||
margin-left: 12px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #e6e6e6;
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
top: 2px;
|
||||
position: relative;
|
||||
transition: .2s;
|
||||
|
||||
@include icon( before, check );
|
||||
&:before {
|
||||
opacity: 0;
|
||||
color: #fff;
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
transition: .2s;
|
||||
}
|
||||
}
|
||||
|
||||
.fancytree-selected span.fancytree-checkbox {
|
||||
border: 1px solid #17a8e3;
|
||||
background-color: #17a8e3;
|
||||
|
||||
&:before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fancytree-expanded span.fancytree-checkbox {
|
||||
margin-left: 11px;
|
||||
}
|
||||
|
||||
// Unselectable is dimmed, without hover effects
|
||||
.fancytree-unselectable {
|
||||
background-color: transparent !important;
|
||||
|
||||
// Fix for bug in library.
|
||||
&.fancytree-selected {
|
||||
margin-left: -9px;
|
||||
|
||||
span.fancytree-expander {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
span.fancytree-checkbox {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #e6e6e6;
|
||||
|
||||
&:before {
|
||||
color: #e6e6e6 !important;
|
||||
}
|
||||
}
|
||||
|
||||
span.fancytree-title {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
span.fancytree-expander,
|
||||
span.fancytree-icon,
|
||||
span.fancytree-checkbox,
|
||||
span.fancytree-title {
|
||||
opacity: 0.4;
|
||||
filter: alpha(opacity=40);
|
||||
|
||||
&:before {
|
||||
color: #666 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Node type icon
|
||||
* Note: IE6 doesn't correctly evaluate multiples class names,
|
||||
* so we create combined class names that can be used in the CSS.
|
||||
*
|
||||
* Prefix: fancytree-ico-
|
||||
* 1st character: 'e': expanded, 'c': collapsed
|
||||
* 2nd character (optional): 'f': folder
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
span.fancytree-icon:before { // Default icon
|
||||
margin-left: 10px;
|
||||
font-family: wpmudev-plugin-icons, sans-serif;
|
||||
font-size: 16px;
|
||||
color: #AAA;
|
||||
content: 'D';
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
/* Documents */
|
||||
.fancytree-ico-c span.fancytree-icon:before { // Collapsed folder (empty)
|
||||
content: 'D';
|
||||
}
|
||||
.fancytree-has-children.fancytree-ico-c span.fancytree-icon:before { // Collapsed folder (not empty)
|
||||
content: 'D';
|
||||
}
|
||||
.fancytree-ico-e span.fancytree-icon:before { // Expanded folder
|
||||
content: '\BB';
|
||||
}
|
||||
|
||||
/* Folders */
|
||||
.fancytree-exp-n.fancytree-ico-ef span.fancytree-icon:before,
|
||||
.fancytree-exp-nl.fancytree-ico-ef span.fancytree-icon:before,
|
||||
.fancytree-ico-cf span.fancytree-icon:before { // Collapsed folder (empty)
|
||||
content: '\2D8';
|
||||
}
|
||||
.fancytree-has-children.fancytree-ico-cf span.fancytree-icon:before { // Collapsed folder (not empty)
|
||||
content: '\2D8';
|
||||
}
|
||||
.fancytree-ico-ef span.fancytree-icon:before { // Expanded folder
|
||||
content: '\BB';
|
||||
}
|
||||
|
||||
// 'Loading' status overrides all others
|
||||
.fancytree-loading span.fancytree-expander:before,
|
||||
.fancytree-statusnode-loading span.fancytree-icon:before {
|
||||
content: 'N';
|
||||
display: inline-block;
|
||||
animation: spin 1.3s linear infinite;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Node titles and highlighting
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
span.fancytree-node {
|
||||
display: inherit;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
min-height: 40px;
|
||||
|
||||
&:not(.fancytree-unselectable):hover {
|
||||
background-color: #F8F8F8;
|
||||
}
|
||||
}
|
||||
span.fancytree-title {
|
||||
color: #666; // inherit doesn't work on IE
|
||||
cursor: pointer;
|
||||
display: inline-block; // Better alignment, when title contains <br>
|
||||
vertical-align: top;
|
||||
min-height: 20px;
|
||||
padding: 0 3px 0 3px; // Otherwise italic font will be outside right bounds
|
||||
margin: 0 0 0 5px;
|
||||
border: 1px solid transparent; // avoid jumping, when a border is added on hover
|
||||
border-radius: 4px;
|
||||
font-weight: 500;
|
||||
}
|
||||
span.fancytree-node.fancytree-error span.fancytree-title {
|
||||
//color: @fancy-font-error-color;
|
||||
}
|
||||
|
||||
span.fancytree-expanded,
|
||||
span.fancytree-selected {
|
||||
border-radius: 4px;
|
||||
background-color: #F8F8F8;
|
||||
color: #17A8E3;
|
||||
|
||||
span.fancytree-title {
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
span.fancytree-selected {
|
||||
background-color: #E1F6FF;
|
||||
|
||||
span.fancytree-expander:before,
|
||||
span.fancytree-icon:before,
|
||||
span.fancytree-title {
|
||||
color: #17A8E3;
|
||||
}
|
||||
}
|
||||
|
||||
span.fancytree-focused {
|
||||
background-color: #e1e1e1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
216
wp-content/plugins/wp-smushit/_src/scss/modules/_media.scss
Normal file
216
wp-content/plugins/wp-smushit/_src/scss/modules/_media.scss
Normal file
@ -0,0 +1,216 @@
|
||||
/* ****************************************************************************
|
||||
* MEDIA AREA SCSS FILE
|
||||
*/
|
||||
@import "~@wpmudev/shared-ui/scss/functions";
|
||||
@import "~@wpmudev/shared-ui/scss/colors";
|
||||
@import "~@wpmudev/shared-ui/scss/variables";
|
||||
// Override body class
|
||||
$sui-version: 'smush-media';
|
||||
$sui-wrap-class: false;
|
||||
@import "~@wpmudev/shared-ui/scss/mixins";
|
||||
@import "~@wpmudev/shared-ui/scss/tooltips";
|
||||
|
||||
/* ****************************************************************************
|
||||
* MEDIA AREA STYLES
|
||||
*/
|
||||
|
||||
// Set column width.
|
||||
.manage-column.column-smushit {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
// Margin for buttons.
|
||||
.sui-smush-media {
|
||||
.button {
|
||||
margin-right: 5px;
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Smush button loading icon.
|
||||
#ngg-listimages,
|
||||
.column-smushit {
|
||||
.spinner {
|
||||
float: none;
|
||||
|
||||
&.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
.smush-status-links{
|
||||
.smush-upgrade-link {
|
||||
color: #8D00B1;
|
||||
font-size: 12px;
|
||||
}
|
||||
.smush-ignore-utm,.smush-revert-utm{
|
||||
display: block;
|
||||
margin: 6px 0 4px;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
span {
|
||||
float: none !important;;
|
||||
}
|
||||
.smush-cdn-notice {
|
||||
color: #50575E;
|
||||
a {
|
||||
color:#2271B1;
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.smush-status {
|
||||
&.smush-warning,&.smush-ignored,&.smush-success{
|
||||
padding-left:17px;
|
||||
position: relative;
|
||||
&:before{
|
||||
content:"";
|
||||
background: url('../images/icon-warning.png' ) no-repeat 0 0;
|
||||
position: absolute;
|
||||
width:12px;
|
||||
height:12px;
|
||||
background-size: contain;
|
||||
left: 0;
|
||||
top:3px;
|
||||
}
|
||||
}
|
||||
&.smush-ignored{
|
||||
&:before{
|
||||
background-image: url('../images/icon-ignored.png' ) !important;
|
||||
}
|
||||
}
|
||||
&.smush-success{
|
||||
&:before{
|
||||
background-image: url('../images/icon-success.png' ) !important;
|
||||
}
|
||||
}
|
||||
.sui-icon-warning-media-lib {
|
||||
margin-right:4px;
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
}
|
||||
.column-smushit .smush-status{
|
||||
color:#50575E;
|
||||
}
|
||||
// Stats table.
|
||||
.sui-smush-media {
|
||||
table.wp-smush-stats-holder {
|
||||
width: 100%;
|
||||
border: 1px solid #E6E6E6;
|
||||
border-radius: 4px;
|
||||
margin-top: 6px;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
thead {
|
||||
th.smush-stats-header {
|
||||
padding: 8px 10px;
|
||||
border-bottom: 1px solid #E6E6E6 !important;
|
||||
color: #32373D;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.23px;
|
||||
line-height: 16px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
tr {
|
||||
border: 1px solid #E6E6E6;
|
||||
}
|
||||
td {
|
||||
overflow-wrap: break-word;
|
||||
vertical-align: middle;
|
||||
padding: 8px 10px;
|
||||
color: #555555;
|
||||
font-size: 11px;
|
||||
letter-spacing: -0.21px;
|
||||
line-height: 16px;
|
||||
border-bottom: 1px solid #E6E6E6;
|
||||
&:first-of-type {
|
||||
max-width: 110px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override !important set from WordPress.
|
||||
#the-list {
|
||||
.sui-smush-media {
|
||||
thead {
|
||||
th.smush-stats-header {
|
||||
border-bottom: 1px solid #E6E6E6 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Responsive table for list mode.
|
||||
@media screen and (max-width: 1024px) {
|
||||
.wp-list-table .smushit {
|
||||
table.wp-smush-stats-holder {
|
||||
th {
|
||||
display: table-cell;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
tr td {
|
||||
word-wrap: break-word;
|
||||
display: table-cell !important;
|
||||
&:first-child {
|
||||
border-right: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
&:last-child {
|
||||
box-sizing: border-box;
|
||||
float: none;
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NextGen Integration.
|
||||
.iedit .wp-smush-action,
|
||||
.iedit .smush-stats-details {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
/*NextGen Gallery stats*/
|
||||
#ngg-listimages {
|
||||
table.wp-smush-stats-holder {
|
||||
table-layout: fixed;
|
||||
border: 1px solid lightgray;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
td,
|
||||
th {
|
||||
border: 1px solid #CECECE;
|
||||
}
|
||||
}
|
||||
.column-7 {
|
||||
width: 300px;
|
||||
}
|
||||
.spinner {
|
||||
width: auto;
|
||||
padding-left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
/** NextGen Gallery tr height, to show the progress bar properly for alternate rows **/
|
||||
.alternate.iedit {
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
/** Allows to click on button, otherwise row-actions from NextGen interferes **/
|
||||
.wp-smush-nextgen-send {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/* ****************************************************************************
|
||||
* MODULE: VARIABLES
|
||||
*/
|
||||
|
||||
$font--path: "../fonts" !default;
|
||||
$img--path: "../images" !default;
|
||||
|
||||
$sui-font-path: '~@wpmudev/shared-ui/dist/fonts/';
|
||||
|
||||
$summary-image: '#{$img--path}/smush-graphic-dashboard-summary.svg';
|
||||
|
||||
// Promo banners for free footer
|
||||
$cross-sell-1: 'hummingbird';
|
||||
$cross-sell-2: 'defender';
|
||||
$cross-sell-3: 'smartcrawl';
|
||||
|
||||
$main-color: #17A8E3;
|
||||
$text-color: #333;
|
||||
$border-radius: 4px;
|
||||
|
||||
$upgrade-image: '../../app/assets/images/hero@2x.png';
|
||||
$upgrade-image-mobile: '../../app/assets/images/hero.png';
|
212
wp-content/plugins/wp-smushit/_src/scss/modules/_webp.scss
Normal file
212
wp-content/plugins/wp-smushit/_src/scss/modules/_webp.scss
Normal file
@ -0,0 +1,212 @@
|
||||
/**
|
||||
* Webp styles
|
||||
*
|
||||
* @since 3.8.0
|
||||
*/
|
||||
|
||||
@include body-class(true) {
|
||||
|
||||
#smush-box-webp-webp {
|
||||
|
||||
.smush-webp-supported-browser {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 5px;
|
||||
margin-right: 10px;
|
||||
border-radius: 4px;
|
||||
background-color: #F2F2F2;
|
||||
display: inline-block;
|
||||
|
||||
img {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#smush-box-webp-wizard {
|
||||
.sui-row-with-sidenav {
|
||||
margin-bottom: 0;
|
||||
|
||||
.sui-sidenav {
|
||||
padding: 30px;
|
||||
border-top-left-radius: $border-radius;
|
||||
background-color: #F8F8F8;
|
||||
|
||||
.smush-wizard-bar-subtitle {
|
||||
font-size: 11px;
|
||||
line-height: 20px;
|
||||
font-weight: 700;
|
||||
color: #AAAAAA;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.smush-sidenav-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 33px;
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.smush-wizard-steps-container {
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
|
||||
@include media(max-width, lg) {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
.smush-wizard-bar-step {
|
||||
display: inline-block;
|
||||
font-size: 13px;
|
||||
color: #AAAAAA;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 0;
|
||||
|
||||
.smush-wizard-bar-step-number {
|
||||
display: inline-block;
|
||||
margin-right: 10px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
font-size: 11px;
|
||||
background-color: #F2F2F2;
|
||||
border: 1px solid #DDDDDD;
|
||||
|
||||
@include media(max-width, lg) {
|
||||
display: block;
|
||||
margin: 0 auto 5px auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #DDDDDD;
|
||||
}
|
||||
|
||||
&.current {
|
||||
color: #333333;
|
||||
|
||||
.smush-wizard-bar-step-number {
|
||||
background-color: #FFFFFF;
|
||||
border-color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
&.done .smush-wizard-bar-step-number {
|
||||
background-color: #1ABC9C;
|
||||
border-color: #1ABC9C;
|
||||
|
||||
.sui-icon-check::before {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
@include media(min-width, lg) {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@include media(max-width, lg) {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
|
||||
line {
|
||||
stroke-width: 4px;
|
||||
}
|
||||
|
||||
&.smush-svg-desktop {
|
||||
height: 40px;
|
||||
width: 22px;
|
||||
margin-left: 10px;
|
||||
display: none;
|
||||
|
||||
@include media(min-width, lg) {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.smush-svg-mobile {
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
display: block;
|
||||
margin-bottom: -14px;
|
||||
padding: 0 35px;
|
||||
|
||||
@include media(min-width, lg) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media(max-width, sm) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.smush-wizard-steps-content-wrapper {
|
||||
padding: 20px;
|
||||
|
||||
.smush-wizard-steps-content {
|
||||
padding: 0 70px;
|
||||
text-align: center;
|
||||
|
||||
&:first-child {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.smush-step-indicator {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@include media(max-width, sm) {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.smush-wizard-step-1 {
|
||||
|
||||
.sui-box-selectors {
|
||||
padding-left: 115px;
|
||||
padding-right: 115px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
&.smush-wizard-step-2 {
|
||||
|
||||
.smush-wizard-rules-wrapper {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.sui-tabs-menu {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@include media(min-width, sm) {
|
||||
padding: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
360
wp-content/plugins/wp-smushit/_src/scss/resize-detection.scss
Normal file
360
wp-content/plugins/wp-smushit/_src/scss/resize-detection.scss
Normal file
@ -0,0 +1,360 @@
|
||||
@import url('https://fonts.bunny.net/css?family=Roboto:400,500,700');
|
||||
@import "modules/variables";
|
||||
$font--path: '~@wpmudev/shared-ui/dist/fonts/';
|
||||
|
||||
@font-face {
|
||||
font-family: "wpmudev-plugin-icons";
|
||||
src: url('#{$font--path}/wpmudev-plugin-icons.eot?');
|
||||
src: url('#{$font--path}/wpmudev-plugin-icons.eot?') format('embedded-opentype'),
|
||||
url('#{$font--path}/wpmudev-plugin-icons.ttf') format('truetype'),
|
||||
url('#{$font--path}/wpmudev-plugin-icons.woff') format('woff'),
|
||||
url('#{$font--path}/wpmudev-plugin-icons.woff2') format('woff2'),
|
||||
url('#{$font--path}/wpmudev-plugin-icons.svg') format('svg');
|
||||
font-weight: 400;
|
||||
font-style: normal
|
||||
}
|
||||
|
||||
@media screen and ( max-width: 800px ) {
|
||||
#smush-image-bar-toggle,
|
||||
#smush-image-bar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and ( min-width: 800px ) {
|
||||
.smush-detected-img {
|
||||
border-radius: 5px;
|
||||
transition: all 0.5s ease;
|
||||
box-shadow: 0 0 0 5px #FECF2F;
|
||||
}
|
||||
|
||||
#smush-image-bar-toggle {
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
right: 330px;
|
||||
height: 50px;
|
||||
width: 60px;
|
||||
z-index: 9999999;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background-color: #FFF;
|
||||
box-shadow: inset 2px 0 0 0 #FECF2F, -13px 5px 20px 0 rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition-property: all;
|
||||
transition-duration: .5s;
|
||||
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
|
||||
|
||||
&.closed {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.smush-toggle-success {
|
||||
box-shadow: inset 2px 0 0 0 #1abc9c, -13px 5px 20px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
i.sui-icon-info,
|
||||
i.sui-icon-loader {
|
||||
font-family: "wpmudev-plugin-icons" !important;
|
||||
font-style: normal;
|
||||
font-size: 16px;
|
||||
line-height: 50px;
|
||||
color: #FECF2F;
|
||||
}
|
||||
|
||||
i.sui-icon-info:before {
|
||||
content: "I";
|
||||
}
|
||||
|
||||
&.smush-toggle-success i.sui-icon-info {
|
||||
color: #1abc9c;
|
||||
&:before {
|
||||
content: "_";
|
||||
}
|
||||
}
|
||||
|
||||
i.sui-icon-loader {
|
||||
&:before {
|
||||
display: block;
|
||||
content: "N";
|
||||
-webkit-animation: spin 1.3s linear infinite;
|
||||
animation: spin 1.3s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#smush-image-bar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 330px;
|
||||
height: 100%;
|
||||
background-color: #FFF;
|
||||
box-shadow: 0 0 40px 0 rgba(0,0,0,0.1);
|
||||
z-index: 999999;
|
||||
padding: 0 0 20px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
max-width: 330px;
|
||||
transition-property: all;
|
||||
transition-duration: .5s;
|
||||
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
|
||||
|
||||
&.closed {
|
||||
max-width: 0;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
h3, p, strong, span {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
letter-spacing: -0.25px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #333333;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
background-color: #FAFAFA;
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #888888;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: #AAAAAA;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 22px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.smush-resize-box {
|
||||
background-color: #F8F8F8;
|
||||
|
||||
&:first-of-type {
|
||||
border-top: 1px solid #E6E6E6;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
span:first-of-type {
|
||||
color: #888;
|
||||
height: 34px;
|
||||
width: 40px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
border: 1px solid #DDDDDD;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.smush-image-info {
|
||||
background-color: #FFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
padding: 17px 20px;
|
||||
border-bottom: 1px solid #E6E6E6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.smush-front-icons {
|
||||
margin: 0 10px;
|
||||
line-height: 5px;
|
||||
|
||||
&:before {
|
||||
font-family: "wpmudev-plugin-icons" !important;
|
||||
speak: none;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
text-rendering: auto;
|
||||
color: #AAA;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
&.smush-front-icon-arrows-in {
|
||||
&:before {
|
||||
content: '\2264';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.smush-tag {
|
||||
background-color: #fecf2f;
|
||||
color: #333;
|
||||
border-radius: 13px;
|
||||
height: 26px;
|
||||
width: 116px;
|
||||
font-size: 12px;
|
||||
letter-spacing: -0.25px;
|
||||
line-height: 16px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.smush-tag-success {
|
||||
background-color: #1abc9c;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&.smush-tooltip {
|
||||
position: relative;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: "";
|
||||
opacity: 0;
|
||||
backface-visibility: hidden;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
transition: margin .2s, opacity .2s;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border: 5px solid transparent;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
border-top-color: #000000;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: attr(data-tooltip);
|
||||
min-width: 40px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
background: #000000;
|
||||
box-sizing: border-box;
|
||||
color: #FFFFFF;
|
||||
font: 400 12px/18px "Roboto", Arial, sans-serif;
|
||||
text-transform: none;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin: 0 0 10px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&.smush-tooltip-constrained {
|
||||
&:after {
|
||||
min-width: 240px;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.show-description):hover {
|
||||
&:before,
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.show-description):hover,
|
||||
&.show-description {
|
||||
.smush-image-info { background-color: #F8F8F8; }
|
||||
|
||||
span:first-of-type {
|
||||
background-color: #E6E6E6;
|
||||
color: transparent;
|
||||
&:before {
|
||||
font-family: "wpmudev-plugin-icons" !important;
|
||||
font-weight: 400;
|
||||
content: "";
|
||||
color: #666;
|
||||
margin-right: -7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.smush-image-description {
|
||||
display: none;
|
||||
border-radius: 4px;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0 2px 0 0 #DDDDDD;
|
||||
margin: 0 20px 20px;
|
||||
padding: 20px;
|
||||
color: #888888;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 13px;
|
||||
letter-spacing: -0.25px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
&.show-description {
|
||||
padding-bottom: 1px;
|
||||
border-bottom: 1px solid #E6E6E6;
|
||||
|
||||
.smush-image-info { border-bottom: 0; }
|
||||
.smush-image-description { display: block; }
|
||||
|
||||
span:first-of-type {
|
||||
background-color: #FECF2F;
|
||||
border-color: #FECF2F;
|
||||
&:before { color: #333; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#smush-image-bar-notice {
|
||||
display: none;
|
||||
margin: 20px;
|
||||
border: 1px solid #E6E6E6;
|
||||
border-left: 2px solid #1abc9c;
|
||||
border-radius: 4px;
|
||||
padding: 15px 20px 15px 25px;
|
||||
|
||||
p:before {
|
||||
position: absolute;
|
||||
left: 42px;
|
||||
font-family: "wpmudev-plugin-icons" !important;
|
||||
font-weight: 400;
|
||||
content: "_";
|
||||
color: #1abc9c;
|
||||
margin-right: -7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user