sss
Signed-off-by: Jeff <jeff@gotenzing.com>
Showing
489 changed files
with
4987 additions
and
0 deletions
558 Bytes
wp-content/plugins/wp-smushit/_src/js/app.js
0 → 100644
| 1 | import '../scss/app.scss'; | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Admin modules | ||
| 5 | */ | ||
| 6 | |||
| 7 | const WP_Smush = WP_Smush || {}; | ||
| 8 | window.WP_Smush = WP_Smush; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * IE polyfill for includes. | ||
| 12 | * | ||
| 13 | * @since 3.1.0 | ||
| 14 | * @param {string} search | ||
| 15 | * @param {number} start | ||
| 16 | * @return {boolean} Returns true if searchString appears as a substring of the result of converting this | ||
| 17 | * object to a String, at one or more positions that are | ||
| 18 | * greater than or equal to position; otherwise, returns false. | ||
| 19 | */ | ||
| 20 | if ( ! String.prototype.includes ) { | ||
| 21 | String.prototype.includes = function( search, start ) { | ||
| 22 | if ( typeof start !== 'number' ) { | ||
| 23 | start = 0; | ||
| 24 | } | ||
| 25 | |||
| 26 | if ( start + search.length > this.length ) { | ||
| 27 | return false; | ||
| 28 | } | ||
| 29 | return this.indexOf( search, start ) !== -1; | ||
| 30 | }; | ||
| 31 | } | ||
| 32 | |||
| 33 | require( './modules/helpers' ); | ||
| 34 | require( './modules/admin' ); | ||
| 35 | require( './modules/admin-common' ); | ||
| 36 | require( './modules/bulk-smush' ); | ||
| 37 | require( './modules/background-process' ); | ||
| 38 | require( './modules/onboarding' ); | ||
| 39 | require( './modules/directory-smush' ); | ||
| 40 | require( './smush/cdn' ); | ||
| 41 | require( './smush/webp' ); | ||
| 42 | require( './smush/lazy-load' ); | ||
| 43 | require( './modules/bulk-restore' ); | ||
| 44 | require( './smush/settings' ); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Notice scripts. | ||
| 48 | * | ||
| 49 | * Notices are used in the following functions: | ||
| 50 | * | ||
| 51 | * @used-by \Smush\Core\Modules\Smush::smush_updated() | ||
| 52 | * @used-by \Smush\Core\Integrations\S3::3_support_required_notice() | ||
| 53 | * @used-by \Smush\App\Abstract_Page::installation_notice() | ||
| 54 | * | ||
| 55 | * TODO: should this be moved out in a separate file like common.scss? | ||
| 56 | */ | ||
| 57 | require( './modules/notice' ); |
| 1 | import '../../scss/resize-detection.scss'; | ||
| 2 | |||
| 3 | /** | ||
| 4 | * Image resize detection (IRD). | ||
| 5 | * | ||
| 6 | * Show all wrongly scaled images with a highlighted border and resize box. | ||
| 7 | * | ||
| 8 | * Made in pure JS. | ||
| 9 | * DO NOT ADD JQUERY SUPPORT!!! | ||
| 10 | * | ||
| 11 | * @since 2.9 | ||
| 12 | */ | ||
| 13 | ( function() { | ||
| 14 | 'use strict'; | ||
| 15 | |||
| 16 | const SmushIRS = { | ||
| 17 | bar: document.getElementById( 'smush-image-bar' ), | ||
| 18 | toggle: document.getElementById( 'smush-image-bar-toggle' ), | ||
| 19 | images: { | ||
| 20 | bigger: [], | ||
| 21 | smaller: [], | ||
| 22 | }, | ||
| 23 | strings: window.wp_smush_resize_vars, | ||
| 24 | |||
| 25 | /** | ||
| 26 | * Init scripts. | ||
| 27 | */ | ||
| 28 | init() { | ||
| 29 | /** | ||
| 30 | * Make sure these are set, before we proceed. | ||
| 31 | */ | ||
| 32 | if ( ! this.bar ) { | ||
| 33 | this.bar = document.getElementById( 'smush-image-bar' ); | ||
| 34 | } | ||
| 35 | if ( ! this.toggle ) { | ||
| 36 | this.toggle = document.getElementById( | ||
| 37 | 'smush-image-bar-toggle' | ||
| 38 | ); | ||
| 39 | } | ||
| 40 | |||
| 41 | this.process(); | ||
| 42 | |||
| 43 | // Register the event handler after everything is done. | ||
| 44 | this.toggle.addEventListener( | ||
| 45 | 'click', | ||
| 46 | this.handleToggleClick.bind( this ) | ||
| 47 | ); | ||
| 48 | }, | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Do image processing. | ||
| 52 | */ | ||
| 53 | process() { | ||
| 54 | const icon = this.toggle.querySelector( 'i' ); | ||
| 55 | |||
| 56 | icon.classList.add( 'sui-icon-loader' ); | ||
| 57 | icon.classList.remove( 'sui-icon-info' ); | ||
| 58 | |||
| 59 | this.detectImages(); | ||
| 60 | |||
| 61 | if ( ! this.images.bigger.length && ! this.images.smaller.length ) { | ||
| 62 | this.toggle.classList.add( 'smush-toggle-success' ); | ||
| 63 | document.getElementById( | ||
| 64 | 'smush-image-bar-notice' | ||
| 65 | ).style.display = 'block'; | ||
| 66 | document.getElementById( | ||
| 67 | 'smush-image-bar-notice-desc' | ||
| 68 | ).style.display = 'none'; | ||
| 69 | } else { | ||
| 70 | this.toggle.classList.remove( 'smush-toggle-success' ); | ||
| 71 | document.getElementById( | ||
| 72 | 'smush-image-bar-notice' | ||
| 73 | ).style.display = 'none'; | ||
| 74 | document.getElementById( | ||
| 75 | 'smush-image-bar-notice-desc' | ||
| 76 | ).style.display = 'block'; | ||
| 77 | this.generateMarkup( 'bigger' ); | ||
| 78 | this.generateMarkup( 'smaller' ); | ||
| 79 | } | ||
| 80 | |||
| 81 | this.toggleDivs(); | ||
| 82 | |||
| 83 | icon.classList.remove( 'sui-icon-loader' ); | ||
| 84 | icon.classList.add( 'sui-icon-info' ); | ||
| 85 | }, | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Various checks to see if the image should be processed. | ||
| 89 | * | ||
| 90 | * @param {Object} image | ||
| 91 | * @return {boolean} Should skip image or not. | ||
| 92 | */ | ||
| 93 | shouldSkipImage( image ) { | ||
| 94 | // Skip avatars. | ||
| 95 | if ( image.classList.contains( 'avatar' ) ) { | ||
| 96 | return true; | ||
| 97 | } | ||
| 98 | |||
| 99 | // Skip images from Smush CDN with auto-resize feature. | ||
| 100 | if ( | ||
| 101 | 'string' === typeof image.getAttribute( 'no-resize-detection' ) | ||
| 102 | ) { | ||
| 103 | return true; | ||
| 104 | } | ||
| 105 | |||
| 106 | // Skip 1x1px images. | ||
| 107 | if ( | ||
| 108 | image.clientWidth === image.clientHeight && | ||
| 109 | 1 === image.clientWidth | ||
| 110 | ) { | ||
| 111 | return true; | ||
| 112 | } | ||
| 113 | |||
| 114 | // Skip 1x1px placeholders. | ||
| 115 | if ( | ||
| 116 | image.naturalWidth === image.naturalHeight && | ||
| 117 | 1 === image.naturalWidth | ||
| 118 | ) { | ||
| 119 | return true; | ||
| 120 | } | ||
| 121 | |||
| 122 | // If width attribute is not set, do not continue. | ||
| 123 | return null === image.clientWidth || null === image.clientHeight; | ||
| 124 | }, | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Get tooltip text. | ||
| 128 | * | ||
| 129 | * @param {Object} props | ||
| 130 | * @return {string} Tooltip. | ||
| 131 | */ | ||
| 132 | getTooltipText( props ) { | ||
| 133 | let tooltipText = ''; | ||
| 134 | |||
| 135 | if ( props.bigger_width || props.bigger_height ) { | ||
| 136 | /** @param {string} strings.large_image */ | ||
| 137 | tooltipText = this.strings.large_image; | ||
| 138 | } else if ( props.smaller_width || props.smaller_height ) { | ||
| 139 | /** @param {string} strings.small_image */ | ||
| 140 | tooltipText = this.strings.small_image; | ||
| 141 | } | ||
| 142 | |||
| 143 | return tooltipText | ||
| 144 | .replace( 'width', props.real_width ) | ||
| 145 | .replace( 'height', props.real_height ); | ||
| 146 | }, | ||
| 147 | |||
| 148 | /** | ||
| 149 | * Generate markup. | ||
| 150 | * | ||
| 151 | * @param {string} type Accepts: 'bigger' or 'smaller'. | ||
| 152 | */ | ||
| 153 | generateMarkup( type ) { | ||
| 154 | this.images[ type ].forEach( ( image, index ) => { | ||
| 155 | const item = document.createElement( 'div' ), | ||
| 156 | tooltip = this.getTooltipText( image.props ); | ||
| 157 | |||
| 158 | item.setAttribute( | ||
| 159 | 'class', | ||
| 160 | 'smush-resize-box smush-tooltip smush-tooltip-constrained' | ||
| 161 | ); | ||
| 162 | item.setAttribute( 'data-tooltip', tooltip ); | ||
| 163 | item.setAttribute( 'data-image', image.class ); | ||
| 164 | item.addEventListener( 'click', ( e ) => | ||
| 165 | this.highlightImage( e ) | ||
| 166 | ); | ||
| 167 | |||
| 168 | item.innerHTML = ` | ||
| 169 | <div class="smush-image-info"> | ||
| 170 | <span>${ index + 1 }</span> | ||
| 171 | <span class="smush-tag">${ image.props.computed_width } x ${ image.props.computed_height }px</span> | ||
| 172 | <i class="smush-front-icons smush-front-icon-arrows-in" aria-hidden="true"> </i> | ||
| 173 | <span class="smush-tag smush-tag-success">${ image.props.real_width } × ${ image.props.real_height }px</span> | ||
| 174 | </div> | ||
| 175 | <div class="smush-image-description">${ tooltip }</div> | ||
| 176 | `; | ||
| 177 | |||
| 178 | document | ||
| 179 | .getElementById( 'smush-image-bar-items-' + type ) | ||
| 180 | .appendChild( item ); | ||
| 181 | } ); | ||
| 182 | }, | ||
| 183 | |||
| 184 | /** | ||
| 185 | * Show/hide sections based on images. | ||
| 186 | */ | ||
| 187 | toggleDivs() { | ||
| 188 | const types = [ 'bigger', 'smaller' ]; | ||
| 189 | types.forEach( ( type ) => { | ||
| 190 | const div = document.getElementById( | ||
| 191 | 'smush-image-bar-items-' + type | ||
| 192 | ); | ||
| 193 | if ( 0 === this.images[ type ].length ) { | ||
| 194 | div.style.display = 'none'; | ||
| 195 | } else { | ||
| 196 | div.style.display = 'block'; | ||
| 197 | } | ||
| 198 | } ); | ||
| 199 | }, | ||
| 200 | |||
| 201 | /** | ||
| 202 | * Scroll the selected image into view and highlight it. | ||
| 203 | * | ||
| 204 | * @param {Object} e | ||
| 205 | */ | ||
| 206 | highlightImage( e ) { | ||
| 207 | this.removeSelection(); | ||
| 208 | |||
| 209 | const el = document.getElementsByClassName( | ||
| 210 | e.currentTarget.dataset.image | ||
| 211 | ); | ||
| 212 | if ( 'undefined' !== typeof el[ 0 ] ) { | ||
| 213 | // Display description box. | ||
| 214 | e.currentTarget.classList.toggle( 'show-description' ); | ||
| 215 | |||
| 216 | // Scroll and flash image. | ||
| 217 | el[ 0 ].scrollIntoView( { | ||
| 218 | behavior: 'smooth', | ||
| 219 | block: 'center', | ||
| 220 | inline: 'nearest', | ||
| 221 | } ); | ||
| 222 | el[ 0 ].style.opacity = '0.5'; | ||
| 223 | setTimeout( () => { | ||
| 224 | el[ 0 ].style.opacity = '1'; | ||
| 225 | }, 1000 ); | ||
| 226 | } | ||
| 227 | }, | ||
| 228 | |||
| 229 | /** | ||
| 230 | * Handle click on the toggle item. | ||
| 231 | */ | ||
| 232 | handleToggleClick() { | ||
| 233 | this.bar.classList.toggle( 'closed' ); | ||
| 234 | this.toggle.classList.toggle( 'closed' ); | ||
| 235 | this.removeSelection(); | ||
| 236 | }, | ||
| 237 | |||
| 238 | /** | ||
| 239 | * Remove selected items. | ||
| 240 | */ | ||
| 241 | removeSelection() { | ||
| 242 | const items = document.getElementsByClassName( 'show-description' ); | ||
| 243 | if ( items.length > 0 ) { | ||
| 244 | Array.from( items ).forEach( ( div ) => | ||
| 245 | div.classList.remove( 'show-description' ) | ||
| 246 | ); | ||
| 247 | } | ||
| 248 | }, | ||
| 249 | |||
| 250 | /** | ||
| 251 | * Function to highlight all scaled images. | ||
| 252 | * | ||
| 253 | * Add yellow border and then show one small box to | ||
| 254 | * resize the images as per the required size, on fly. | ||
| 255 | */ | ||
| 256 | detectImages() { | ||
| 257 | const images = document.getElementsByTagName( 'img' ); | ||
| 258 | for ( const image of images ) { | ||
| 259 | if ( this.shouldSkipImage( image ) ) { | ||
| 260 | continue; | ||
| 261 | } | ||
| 262 | |||
| 263 | // Get defined width and height. | ||
| 264 | const props = { | ||
| 265 | real_width: image.clientWidth, | ||
| 266 | real_height: image.clientHeight, | ||
| 267 | computed_width: image.naturalWidth, | ||
| 268 | computed_height: image.naturalHeight, | ||
| 269 | bigger_width: image.clientWidth * 1.5 < image.naturalWidth, | ||
| 270 | bigger_height: | ||
| 271 | image.clientHeight * 1.5 < image.naturalHeight, | ||
| 272 | smaller_width: image.clientWidth > image.naturalWidth, | ||
| 273 | smaller_height: image.clientHeight > image.naturalHeight, | ||
| 274 | }; | ||
| 275 | |||
| 276 | // In case image is in correct size, do not continue. | ||
| 277 | if ( | ||
| 278 | ! props.bigger_width && | ||
| 279 | ! props.bigger_height && | ||
| 280 | ! props.smaller_width && | ||
| 281 | ! props.smaller_height | ||
| 282 | ) { | ||
| 283 | continue; | ||
| 284 | } | ||
| 285 | |||
| 286 | const imgType = | ||
| 287 | props.bigger_width || props.bigger_height | ||
| 288 | ? 'bigger' | ||
| 289 | : 'smaller', | ||
| 290 | imageClass = | ||
| 291 | 'smush-image-' + ( this.images[ imgType ].length + 1 ); | ||
| 292 | |||
| 293 | // Fill the images arrays. | ||
| 294 | this.images[ imgType ].push( { | ||
| 295 | src: image, | ||
| 296 | props, | ||
| 297 | class: imageClass, | ||
| 298 | } ); | ||
| 299 | |||
| 300 | /** | ||
| 301 | * Add class to original image. | ||
| 302 | * Can't add two classes in single add(), because no support in IE11. | ||
| 303 | * image.classList.add('smush-detected-img', imageClass); | ||
| 304 | */ | ||
| 305 | image.classList.add( 'smush-detected-img' ); | ||
| 306 | image.classList.add( imageClass ); | ||
| 307 | } | ||
| 308 | }, // End detectImages() | ||
| 309 | |||
| 310 | /** | ||
| 311 | * Allows refreshing the list. A good way is to refresh on lazyload actions. | ||
| 312 | * | ||
| 313 | * @since 3.6.0 | ||
| 314 | */ | ||
| 315 | refresh() { | ||
| 316 | // Clear out classes on DOM. | ||
| 317 | for ( let id in this.images.bigger ) { | ||
| 318 | if ( this.images.bigger.hasOwnProperty( id ) ) { | ||
| 319 | this.images.bigger[ id ].src.classList.remove( | ||
| 320 | 'smush-detected-img' | ||
| 321 | ); | ||
| 322 | this.images.bigger[ id ].src.classList.remove( | ||
| 323 | 'smush-image-' + ++id | ||
| 324 | ); | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | for ( let id in this.images.smaller ) { | ||
| 329 | if ( this.images.smaller.hasOwnProperty( id ) ) { | ||
| 330 | this.images.smaller[ id ].src.classList.remove( | ||
| 331 | 'smush-detected-img' | ||
| 332 | ); | ||
| 333 | this.images.smaller[ id ].src.classList.remove( | ||
| 334 | 'smush-image-' + ++id | ||
| 335 | ); | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | this.images = { | ||
| 340 | bigger: [], | ||
| 341 | smaller: [], | ||
| 342 | }; | ||
| 343 | |||
| 344 | // This might be overkill - there will probably never be a situation when there are less images than on | ||
| 345 | // initial page load. | ||
| 346 | const elements = document.getElementsByClassName( | ||
| 347 | 'smush-resize-box' | ||
| 348 | ); | ||
| 349 | while ( elements.length > 0 ) { | ||
| 350 | elements[ 0 ].remove(); | ||
| 351 | } | ||
| 352 | |||
| 353 | this.process(); | ||
| 354 | }, | ||
| 355 | }; // End WP_Smush_IRS | ||
| 356 | |||
| 357 | /** | ||
| 358 | * After page load, initialize toggle event. | ||
| 359 | */ | ||
| 360 | window.addEventListener( 'DOMContentLoaded', () => SmushIRS.init() ); | ||
| 361 | window.addEventListener( 'lazyloaded', () => SmushIRS.refresh() ); | ||
| 362 | }() ); |
| 1 | import '../scss/common.scss'; | ||
| 2 | |||
| 3 | /* global ajaxurl */ | ||
| 4 | |||
| 5 | document.addEventListener('DOMContentLoaded', function () { | ||
| 6 | const dismissNoticeButton = document.querySelectorAll( | ||
| 7 | '.smush-dismissible-notice .smush-dismiss-notice-button' | ||
| 8 | ); | ||
| 9 | dismissNoticeButton.forEach((button) => { | ||
| 10 | button.addEventListener('click', dismissNotice); | ||
| 11 | }); | ||
| 12 | |||
| 13 | function dismissNotice(event) { | ||
| 14 | event.preventDefault(); | ||
| 15 | |||
| 16 | const button = event.target; | ||
| 17 | const notice = button.closest('.smush-dismissible-notice'); | ||
| 18 | const key = notice.getAttribute('data-key'); | ||
| 19 | |||
| 20 | const xhr = new XMLHttpRequest(); | ||
| 21 | xhr.open( | ||
| 22 | 'POST', | ||
| 23 | ajaxurl + '?action=smush_dismiss_notice&key=' + key + '&_ajax_nonce=' + smush_global.nonce, | ||
| 24 | true | ||
| 25 | ); | ||
| 26 | xhr.onload = () => { | ||
| 27 | if (notice) { | ||
| 28 | notice.querySelector('button.notice-dismiss').dispatchEvent(new MouseEvent('click', { | ||
| 29 | view: window, | ||
| 30 | bubbles: true, | ||
| 31 | cancelable: true | ||
| 32 | })); | ||
| 33 | } | ||
| 34 | }; | ||
| 35 | xhr.send(); | ||
| 36 | } | ||
| 37 | }); |
| 1 | /* global wp_smush_mixpanel */ | ||
| 2 | |||
| 3 | import mixpanel from "mixpanel-browser"; | ||
| 4 | |||
| 5 | export default class MixPanel { | ||
| 6 | constructor() { | ||
| 7 | this.mixpanelInstance = mixpanel.init(wp_smush_mixpanel.token, { | ||
| 8 | opt_out_tracking_by_default: !wp_smush_mixpanel.opt_in, | ||
| 9 | loaded: (mixpanel) => { | ||
| 10 | mixpanel.identify(wp_smush_mixpanel.unique_id); | ||
| 11 | mixpanel.register(wp_smush_mixpanel.super_properties); | ||
| 12 | } | ||
| 13 | }, 'smush'); | ||
| 14 | } | ||
| 15 | |||
| 16 | track(event, properties = {}) { | ||
| 17 | this.mixpanelInstance.track(event, properties); | ||
| 18 | } | ||
| 19 | |||
| 20 | trackBulkSmushCompleted(totalSavingsSize, totalImageCount, optimizationPercentage, savingsPercentage) { | ||
| 21 | this.track('Bulk Smush Completed', { | ||
| 22 | 'Total Savings': totalSavingsSize, | ||
| 23 | 'Total Images': totalImageCount, | ||
| 24 | 'Media Optimization Percentage': optimizationPercentage, | ||
| 25 | 'Percentage of Savings': savingsPercentage | ||
| 26 | }); | ||
| 27 | } | ||
| 28 | |||
| 29 | trackBulkSmushCancel() { | ||
| 30 | this.track('Bulk Smush Cancelled'); | ||
| 31 | } | ||
| 32 | } |
| 1 | jQuery(function ($) { | ||
| 2 | 'use strict'; | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Handle the Smush Stats link click | ||
| 6 | */ | ||
| 7 | $('body').on('click', 'a.smush-stats-details', function (e) { | ||
| 8 | //If disabled | ||
| 9 | if ($(this).prop('disabled')) { | ||
| 10 | return false; | ||
| 11 | } | ||
| 12 | |||
| 13 | // prevent the default action | ||
| 14 | e.preventDefault(); | ||
| 15 | //Replace the `+` with a `-` | ||
| 16 | const slide_symbol = $(this).find('.stats-toggle'); | ||
| 17 | $(this).parents().eq(1).find('.smush-stats-wrapper').slideToggle(); | ||
| 18 | slide_symbol.text(slide_symbol.text() == '+' ? '-' : '+'); | ||
| 19 | }); | ||
| 20 | }); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | /* global _ */ | ||
| 4 | |||
| 5 | import MixPanel from "../mixpanel"; | ||
| 6 | |||
| 7 | /** | ||
| 8 | * Bulk restore JavaScript code. | ||
| 9 | * | ||
| 10 | * @since 3.2.2 | ||
| 11 | */ | ||
| 12 | (function () { | ||
| 13 | 'use strict'; | ||
| 14 | |||
| 15 | /** | ||
| 16 | * Bulk restore modal. | ||
| 17 | * | ||
| 18 | * @since 3.2.2 | ||
| 19 | */ | ||
| 20 | WP_Smush.restore = { | ||
| 21 | modal: document.getElementById('smush-restore-images-dialog'), | ||
| 22 | contentContainer: document.getElementById('smush-bulk-restore-content'), | ||
| 23 | settings: { | ||
| 24 | slide: 'start', // start, progress or finish. | ||
| 25 | success: 0, | ||
| 26 | errors: [], | ||
| 27 | }, | ||
| 28 | items: [], // total items, 1 item = 1 step. | ||
| 29 | success: [], // successful items restored. | ||
| 30 | errors: [], // failed items. | ||
| 31 | currentStep: 0, | ||
| 32 | totalSteps: 0, | ||
| 33 | |||
| 34 | /** | ||
| 35 | * Init module. | ||
| 36 | */ | ||
| 37 | init() { | ||
| 38 | if (!this.modal) { | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | |||
| 42 | this.settings = { | ||
| 43 | slide: 'start', | ||
| 44 | success: 0, | ||
| 45 | errors: [], | ||
| 46 | }; | ||
| 47 | |||
| 48 | this.mixPanel = new MixPanel(); | ||
| 49 | |||
| 50 | this.resetModalWidth(); | ||
| 51 | this.renderTemplate(); | ||
| 52 | |||
| 53 | // Show the modal. | ||
| 54 | |||
| 55 | window.SUI.openModal( | ||
| 56 | 'smush-restore-images-dialog', | ||
| 57 | 'wpbody-content', | ||
| 58 | undefined, | ||
| 59 | false | ||
| 60 | ); | ||
| 61 | }, | ||
| 62 | |||
| 63 | /** | ||
| 64 | * Update the template, register new listeners. | ||
| 65 | */ | ||
| 66 | renderTemplate() { | ||
| 67 | const template = WP_Smush.onboarding.template('smush-bulk-restore'); | ||
| 68 | const content = template(this.settings); | ||
| 69 | |||
| 70 | if (content) { | ||
| 71 | this.contentContainer.innerHTML = content; | ||
| 72 | } | ||
| 73 | |||
| 74 | this.bindSubmit(); | ||
| 75 | }, | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Reset modal width. | ||
| 79 | * | ||
| 80 | * @since 3.6.0 | ||
| 81 | */ | ||
| 82 | resetModalWidth() { | ||
| 83 | this.modal.style.maxWidth = '460px'; | ||
| 84 | this.modal.querySelector('.sui-box').style.maxWidth = '460px'; | ||
| 85 | }, | ||
| 86 | |||
| 87 | /** | ||
| 88 | * Catch "Finish setup wizard" button click. | ||
| 89 | */ | ||
| 90 | bindSubmit() { | ||
| 91 | const confirmButton = this.modal.querySelector( | ||
| 92 | 'button[id="smush-bulk-restore-button"]' | ||
| 93 | ); | ||
| 94 | const self = this; | ||
| 95 | |||
| 96 | if (confirmButton) { | ||
| 97 | confirmButton.addEventListener('click', function (e) { | ||
| 98 | e.preventDefault(); | ||
| 99 | self.resetModalWidth(); | ||
| 100 | |||
| 101 | self.settings = { slide: 'progress' }; | ||
| 102 | self.errors = []; | ||
| 103 | |||
| 104 | self.renderTemplate(); | ||
| 105 | self.initScan(); | ||
| 106 | |||
| 107 | self.mixPanel.track('Bulk Restore Triggered'); | ||
| 108 | }); | ||
| 109 | } | ||
| 110 | }, | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Cancel the bulk restore. | ||
| 114 | */ | ||
| 115 | cancel() { | ||
| 116 | if ( | ||
| 117 | 'start' === this.settings.slide || | ||
| 118 | 'finish' === this.settings.slide | ||
| 119 | ) { | ||
| 120 | // Hide the modal. | ||
| 121 | window.SUI.closeModal(); | ||
| 122 | } else { | ||
| 123 | this.updateProgressBar(true); | ||
| 124 | window.location.reload(); | ||
| 125 | } | ||
| 126 | }, | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Update progress bar during directory smush. | ||
| 130 | * | ||
| 131 | * @param {boolean} cancel Cancel status. | ||
| 132 | */ | ||
| 133 | updateProgressBar(cancel = false) { | ||
| 134 | let progress = 0; | ||
| 135 | if (0 < this.currentStep) { | ||
| 136 | progress = Math.min( | ||
| 137 | Math.round((this.currentStep * 100) / this.totalSteps), | ||
| 138 | 99 | ||
| 139 | ); | ||
| 140 | } | ||
| 141 | |||
| 142 | if (progress > 100) { | ||
| 143 | progress = 100; | ||
| 144 | } | ||
| 145 | |||
| 146 | // Update progress bar | ||
| 147 | this.modal.querySelector('.sui-progress-text span').innerHTML = | ||
| 148 | progress + '%'; | ||
| 149 | this.modal.querySelector('.sui-progress-bar span').style.width = | ||
| 150 | progress + '%'; | ||
| 151 | |||
| 152 | const statusDiv = this.modal.querySelector( | ||
| 153 | '.sui-progress-state-text' | ||
| 154 | ); | ||
| 155 | if (progress >= 90) { | ||
| 156 | statusDiv.innerHTML = 'Finalizing...'; | ||
| 157 | } else if (cancel) { | ||
| 158 | statusDiv.innerHTML = 'Cancelling...'; | ||
| 159 | } else { | ||
| 160 | statusDiv.innerHTML = | ||
| 161 | this.currentStep + | ||
| 162 | '/' + | ||
| 163 | this.totalSteps + | ||
| 164 | ' ' + | ||
| 165 | 'images restored'; | ||
| 166 | } | ||
| 167 | }, | ||
| 168 | |||
| 169 | /** | ||
| 170 | * First step in bulk restore - get the bulk attachment count. | ||
| 171 | */ | ||
| 172 | initScan() { | ||
| 173 | const self = this; | ||
| 174 | const _nonce = document.getElementById('_wpnonce'); | ||
| 175 | |||
| 176 | const xhr = new XMLHttpRequest(); | ||
| 177 | xhr.open('POST', ajaxurl + '?action=get_image_count', true); | ||
| 178 | xhr.setRequestHeader( | ||
| 179 | 'Content-type', | ||
| 180 | 'application/x-www-form-urlencoded' | ||
| 181 | ); | ||
| 182 | xhr.onload = () => { | ||
| 183 | if (200 === xhr.status) { | ||
| 184 | const res = JSON.parse(xhr.response); | ||
| 185 | if ('undefined' !== typeof res.data.items) { | ||
| 186 | self.items = res.data.items; | ||
| 187 | self.totalSteps = res.data.items.length; | ||
| 188 | self.step(); | ||
| 189 | } | ||
| 190 | } else { | ||
| 191 | window.console.log( | ||
| 192 | 'Request failed. Returned status of ' + xhr.status | ||
| 193 | ); | ||
| 194 | } | ||
| 195 | }; | ||
| 196 | xhr.send('_ajax_nonce=' + _nonce.value); | ||
| 197 | }, | ||
| 198 | |||
| 199 | /** | ||
| 200 | * Execute a scan step recursively | ||
| 201 | */ | ||
| 202 | step() { | ||
| 203 | const self = this; | ||
| 204 | const _nonce = document.getElementById('_wpnonce'); | ||
| 205 | |||
| 206 | if (0 < this.items.length) { | ||
| 207 | const item = this.items.pop(); | ||
| 208 | const xhr = new XMLHttpRequest(); | ||
| 209 | xhr.open('POST', ajaxurl + '?action=restore_step', true); | ||
| 210 | xhr.setRequestHeader( | ||
| 211 | 'Content-type', | ||
| 212 | 'application/x-www-form-urlencoded' | ||
| 213 | ); | ||
| 214 | xhr.onload = () => { | ||
| 215 | this.currentStep++; | ||
| 216 | |||
| 217 | if (200 === xhr.status) { | ||
| 218 | const res = JSON.parse(xhr.response); | ||
| 219 | if ( | ||
| 220 | 'undefined' !== typeof res.data.success && | ||
| 221 | res.data.success | ||
| 222 | ) { | ||
| 223 | self.success.push(item); | ||
| 224 | } else { | ||
| 225 | self.errors.push({ | ||
| 226 | id: item, | ||
| 227 | src: res.data.src, | ||
| 228 | thumb: res.data.thumb, | ||
| 229 | link: res.data.link, | ||
| 230 | }); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | self.updateProgressBar(); | ||
| 235 | self.step(); | ||
| 236 | }; | ||
| 237 | xhr.send('item=' + item + '&_ajax_nonce=' + _nonce.value); | ||
| 238 | } else { | ||
| 239 | // Finish. | ||
| 240 | this.settings = { | ||
| 241 | slide: 'finish', | ||
| 242 | success: this.success.length, | ||
| 243 | errors: this.errors, | ||
| 244 | total: this.totalSteps, | ||
| 245 | }; | ||
| 246 | |||
| 247 | self.renderTemplate(); | ||
| 248 | if (0 < this.errors.length) { | ||
| 249 | this.modal.style.maxWidth = '660px'; | ||
| 250 | this.modal.querySelector('.sui-box').style.maxWidth = | ||
| 251 | '660px'; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | }, | ||
| 255 | }; | ||
| 256 | |||
| 257 | /** | ||
| 258 | * Template function (underscores based). | ||
| 259 | * | ||
| 260 | * @type {Function} | ||
| 261 | */ | ||
| 262 | WP_Smush.restore.template = _.memoize((id) => { | ||
| 263 | let compiled; | ||
| 264 | const options = { | ||
| 265 | evaluate: /<#([\s\S]+?)#>/g, | ||
| 266 | interpolate: /{{{([\s\S]+?)}}}/g, | ||
| 267 | escape: /{{([^}]+?)}}(?!})/g, | ||
| 268 | variable: 'data', | ||
| 269 | }; | ||
| 270 | |||
| 271 | return (data) => { | ||
| 272 | _.templateSettings = options; | ||
| 273 | compiled = | ||
| 274 | compiled || _.template(document.getElementById(id).innerHTML); | ||
| 275 | return compiled(data); | ||
| 276 | }; | ||
| 277 | }); | ||
| 278 | })(); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Bulk Smush functionality. | ||
| 6 | * | ||
| 7 | * @since 2.9.0 Moved from admin.js | ||
| 8 | */ | ||
| 9 | |||
| 10 | import Smush from '../smush/smush'; | ||
| 11 | import Fetcher from '../utils/fetcher'; | ||
| 12 | |||
| 13 | ( function( $ ) { | ||
| 14 | 'use strict'; | ||
| 15 | |||
| 16 | WP_Smush.bulk = { | ||
| 17 | init: () => { | ||
| 18 | /** | ||
| 19 | * Handle the Bulk Smush/Bulk re-Smush button click. | ||
| 20 | */ | ||
| 21 | $( '.wp-smush-all' ).on( 'click', function( e ) { | ||
| 22 | e.preventDefault(); | ||
| 23 | |||
| 24 | const bulkRunning = document.getElementById( | ||
| 25 | 'wp-smush-running-notice' | ||
| 26 | ); | ||
| 27 | bulkRunning.classList.add( 'sui-hidden' ); | ||
| 28 | |||
| 29 | // Remove limit exceeded styles. | ||
| 30 | const progress = $( '.wp-smush-bulk-progress-bar-wrapper' ); | ||
| 31 | // TODO: we don't have wp-smush-exceed-limit remove the following line and test | ||
| 32 | progress.removeClass( 'wp-smush-exceed-limit' ); | ||
| 33 | progress | ||
| 34 | .find( '.sui-progress-block .wp-smush-all' ) | ||
| 35 | .addClass( 'sui-hidden' ); | ||
| 36 | progress | ||
| 37 | .find( '.sui-progress-block .wp-smush-cancel-bulk' ) | ||
| 38 | .removeClass( 'sui-hidden' ); | ||
| 39 | if ( bulkRunning ) { | ||
| 40 | document | ||
| 41 | .getElementById( 'bulk-smush-resume-button' ) | ||
| 42 | .classList.add( 'sui-hidden' ); | ||
| 43 | } | ||
| 44 | |||
| 45 | // remove smush-limit-reached-notice. | ||
| 46 | const limitReachedNotice = document.getElementById( 'smush-limit-reached-notice' ); | ||
| 47 | if ( limitReachedNotice ) { | ||
| 48 | limitReachedNotice.classList.add( 'sui-hidden' ); | ||
| 49 | } | ||
| 50 | |||
| 51 | // Disable re-Smush and scan button. | ||
| 52 | // TODO: refine what is disabled. | ||
| 53 | $( | ||
| 54 | '.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' | ||
| 55 | ).prop( 'disabled', true ); | ||
| 56 | |||
| 57 | // Check for IDs, if there is none (unsmushed or lossless), don't call Smush function. | ||
| 58 | /** @param {Array} wp_smushit_data.unsmushed */ | ||
| 59 | if ( | ||
| 60 | 'undefined' === typeof window.wp_smushit_data || | ||
| 61 | ( 0 === window.wp_smushit_data.unsmushed.length && | ||
| 62 | 0 === window.wp_smushit_data.resmush.length ) | ||
| 63 | ) { | ||
| 64 | return false; | ||
| 65 | } | ||
| 66 | |||
| 67 | $( '.wp-smush-remaining' ).addClass( 'sui-hidden' ); | ||
| 68 | |||
| 69 | WP_Smush.bulk.maybeShowCDNUpsellForPreSiteOnStart(); | ||
| 70 | |||
| 71 | // Show loader. | ||
| 72 | progress | ||
| 73 | .find( '.sui-progress-block i.sui-icon-info' ) | ||
| 74 | .removeClass( 'sui-icon-info' ) | ||
| 75 | .addClass( 'sui-loading' ) | ||
| 76 | .addClass( 'sui-icon-loader' ); | ||
| 77 | |||
| 78 | new Smush( $( this ), true ); | ||
| 79 | } ); | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Ignore file from bulk Smush. | ||
| 83 | * | ||
| 84 | * @since 2.9.0 | ||
| 85 | */ | ||
| 86 | $( 'body' ).on( 'click', '.smush-ignore-image', function( e ) { | ||
| 87 | e.preventDefault(); | ||
| 88 | |||
| 89 | const self = $( this ); | ||
| 90 | |||
| 91 | self.prop( 'disabled', true ); | ||
| 92 | self.attr( 'data-tooltip' ); | ||
| 93 | self.removeClass( 'sui-tooltip' ); | ||
| 94 | $.post( ajaxurl, { | ||
| 95 | action: 'ignore_bulk_image', | ||
| 96 | id: self.attr( 'data-id' ), | ||
| 97 | _ajax_nonce: wp_smush_msgs.nonce, | ||
| 98 | } ).done( ( response ) => { | ||
| 99 | if ( self.is( 'a' ) && response.success && 'undefined' !== typeof response.data.links ) { | ||
| 100 | if ( e.target.closest( '.smush-status-links' ) ) { | ||
| 101 | const smushStatus = self.parent().parent().find( '.smush-status' ); | ||
| 102 | smushStatus.text( wp_smush_msgs.ignored ); | ||
| 103 | smushStatus.addClass('smush-ignored'); | ||
| 104 | e.target.closest( '.smush-status-links' ).innerHTML = response.data.links; | ||
| 105 | } else if (e.target.closest( '.smush-bulk-error-row' ) ){ | ||
| 106 | self.addClass('disabled'); | ||
| 107 | e.target.closest( '.smush-bulk-error-row' ).style.opacity = 0.5; | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } ); | ||
| 111 | } ); | ||
| 112 | |||
| 113 | /** | ||
| 114 | * Ignore file from bulk Smush. | ||
| 115 | * | ||
| 116 | * @since 3.12.0 | ||
| 117 | */ | ||
| 118 | const ignoreAll = document.querySelector('.wp_smush_ignore_all_failed_items'); | ||
| 119 | if ( ignoreAll ) { | ||
| 120 | ignoreAll.onclick = (e) => { | ||
| 121 | e.preventDefault(); | ||
| 122 | e.target.setAttribute('disabled',''); | ||
| 123 | e.target.style.cursor = 'progress'; | ||
| 124 | const type = e.target.dataset.type || null; | ||
| 125 | e.target.classList.remove('sui-tooltip'); | ||
| 126 | Fetcher.smush.ignoreAll(type).then((res) => { | ||
| 127 | if ( res.success ) { | ||
| 128 | window.location.reload(); | ||
| 129 | } else { | ||
| 130 | e.target.style.cursor = 'pointer'; | ||
| 131 | e.target.removeAttribute('disabled'); | ||
| 132 | WP_Smush.helpers.showNotice( res ); | ||
| 133 | } | ||
| 134 | }); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | }, | ||
| 138 | maybeShowCDNUpsellForPreSiteOnStart: () => { | ||
| 139 | // Show upsell cdn. | ||
| 140 | const upsell_cdn = document.querySelector('.wp-smush-upsell-cdn'); | ||
| 141 | if ( upsell_cdn ) { | ||
| 142 | upsell_cdn.classList.remove('sui-hidden'); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | }; | ||
| 146 | |||
| 147 | WP_Smush.bulk.init(); | ||
| 148 | } )( jQuery ); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Directory Smush module JavaScript code. | ||
| 6 | * | ||
| 7 | * @since 2.8.1 Separated from admin.js into dedicated file. | ||
| 8 | */ | ||
| 9 | |||
| 10 | import { createTree } from 'jquery.fancytree'; | ||
| 11 | import Scanner from '../smush/directory-scanner'; | ||
| 12 | |||
| 13 | ( function( $ ) { | ||
| 14 | 'use strict'; | ||
| 15 | |||
| 16 | WP_Smush.directory = { | ||
| 17 | selected: [], | ||
| 18 | tree: [], | ||
| 19 | wp_smush_msgs: [], | ||
| 20 | triggered: false, | ||
| 21 | |||
| 22 | init() { | ||
| 23 | const self = this, | ||
| 24 | progressDialog = $( '#wp-smush-progress-dialog' ); | ||
| 25 | |||
| 26 | let totalSteps = 0, | ||
| 27 | currentScanStep = 0; | ||
| 28 | |||
| 29 | // Make sure directory smush vars are set. | ||
| 30 | if ( typeof window.wp_smushit_data.dir_smush !== 'undefined' ) { | ||
| 31 | totalSteps = window.wp_smushit_data.dir_smush.totalSteps; | ||
| 32 | currentScanStep = | ||
| 33 | window.wp_smushit_data.dir_smush.currentScanStep; | ||
| 34 | } | ||
| 35 | |||
| 36 | // Init image scanner. | ||
| 37 | this.scanner = new Scanner( totalSteps, currentScanStep ); | ||
| 38 | |||
| 39 | /** | ||
| 40 | * Smush translation strings. | ||
| 41 | * | ||
| 42 | * @param {Array} wp_smush_msgs | ||
| 43 | */ | ||
| 44 | this.wp_smush_msgs = window.wp_smush_msgs || {}; | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Open the "Select Smush directory" modal. | ||
| 48 | */ | ||
| 49 | $( 'button.wp-smush-browse, a#smush-directory-open-modal' ).on( | ||
| 50 | 'click', | ||
| 51 | function( e ) { | ||
| 52 | e.preventDefault(); | ||
| 53 | |||
| 54 | if ( $( e.currentTarget ).hasClass( 'wp-smush-browse' ) ) { | ||
| 55 | // Hide all the notices. | ||
| 56 | $( 'div.wp-smush-scan-result div.wp-smush-notice' ).hide(); | ||
| 57 | |||
| 58 | // Remove notice. | ||
| 59 | $( 'div.wp-smush-info' ).remove(); | ||
| 60 | } | ||
| 61 | |||
| 62 | window.SUI.openModal( | ||
| 63 | 'wp-smush-list-dialog', | ||
| 64 | e.currentTarget, | ||
| 65 | $( | ||
| 66 | '#wp-smush-list-dialog .sui-box-header [data-modal-close]' | ||
| 67 | )[0], | ||
| 68 | true | ||
| 69 | ); | ||
| 70 | //Display File tree for Directory Smush | ||
| 71 | self.initFileTree(); | ||
| 72 | } | ||
| 73 | ); | ||
| 74 | |||
| 75 | /** | ||
| 76 | * Smush images: Smush in Choose Directory modal clicked | ||
| 77 | */ | ||
| 78 | $( '#wp-smush-select-dir' ).on( 'click', function( e ) { | ||
| 79 | e.preventDefault(); | ||
| 80 | |||
| 81 | $( 'div.wp-smush-list-dialog div.sui-box-body' ).css( { | ||
| 82 | opacity: '0.8', | ||
| 83 | } ); | ||
| 84 | $( 'div.wp-smush-list-dialog div.sui-box-body a' ).off( | ||
| 85 | 'click' | ||
| 86 | ); | ||
| 87 | |||
| 88 | const button = $( this ); | ||
| 89 | |||
| 90 | // Display the spinner. | ||
| 91 | button.addClass('sui-button-onload'); | ||
| 92 | |||
| 93 | const selectedFolders = self.tree.getSelectedNodes(); | ||
| 94 | |||
| 95 | const paths = []; | ||
| 96 | selectedFolders.forEach( function( folder ) { | ||
| 97 | paths.push( folder.key ); | ||
| 98 | } ); | ||
| 99 | |||
| 100 | // Send a ajax request to get a list of all the image files | ||
| 101 | const param = { | ||
| 102 | action: 'image_list', | ||
| 103 | smush_path: paths, | ||
| 104 | image_list_nonce: $( | ||
| 105 | 'input[name="image_list_nonce"]' | ||
| 106 | ).val(), | ||
| 107 | }; | ||
| 108 | |||
| 109 | $.post( ajaxurl, param, function( response ) { | ||
| 110 | if ( response.success ) { | ||
| 111 | // Close the modal. | ||
| 112 | window.SUI.closeModal(); | ||
| 113 | |||
| 114 | self.scanner = new Scanner( response.data, 0 ); | ||
| 115 | self.showProgressDialog( response.data ); | ||
| 116 | self.scanner.scan(); | ||
| 117 | } else { | ||
| 118 | // Remove the spinner. | ||
| 119 | button.removeClass('sui-button-onload'); | ||
| 120 | |||
| 121 | window.SUI.openNotice( | ||
| 122 | 'wp-smush-ajax-notice', | ||
| 123 | response.data.message, | ||
| 124 | { type: 'warning' } | ||
| 125 | ); | ||
| 126 | } | ||
| 127 | } ); | ||
| 128 | } ); | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Cancel scan. | ||
| 132 | */ | ||
| 133 | progressDialog.on( | ||
| 134 | 'click', | ||
| 135 | '#cancel-directory-smush, #dialog-close-div, .wp-smush-cancel-dir', | ||
| 136 | function( e ) { | ||
| 137 | e.preventDefault(); | ||
| 138 | // Display the spinner | ||
| 139 | $( '.wp-smush-cancel-dir' ).addClass( 'sui-button-onload' ); | ||
| 140 | self.scanner | ||
| 141 | .cancel() | ||
| 142 | .done( | ||
| 143 | () => | ||
| 144 | ( window.location.href = | ||
| 145 | self.wp_smush_msgs.directory_url ) | ||
| 146 | ); | ||
| 147 | } | ||
| 148 | ); | ||
| 149 | |||
| 150 | /** | ||
| 151 | * Continue scan. | ||
| 152 | */ | ||
| 153 | progressDialog.on( | ||
| 154 | 'click', | ||
| 155 | '.sui-icon-play, .wp-smush-resume-scan', | ||
| 156 | function( e ) { | ||
| 157 | e.preventDefault(); | ||
| 158 | self.scanner.resume(); | ||
| 159 | } | ||
| 160 | ); | ||
| 161 | |||
| 162 | /** | ||
| 163 | * Check to see if we should open the directory module. | ||
| 164 | * Used to redirect from dashboard page. | ||
| 165 | * | ||
| 166 | * @since 3.8.6 | ||
| 167 | */ | ||
| 168 | const queryString = window.location.search; | ||
| 169 | const urlParams = new URLSearchParams( queryString ); | ||
| 170 | if ( urlParams.has( 'start' ) && ! this.triggered ) { | ||
| 171 | this.triggered = true; | ||
| 172 | $( 'button.wp-smush-browse' ).trigger( 'click' ); | ||
| 173 | } | ||
| 174 | }, | ||
| 175 | |||
| 176 | /** | ||
| 177 | * Init fileTree. | ||
| 178 | */ | ||
| 179 | initFileTree() { | ||
| 180 | const self = this, | ||
| 181 | smushButton = $( 'button#wp-smush-select-dir' ), | ||
| 182 | ajaxSettings = { | ||
| 183 | type: 'GET', | ||
| 184 | url: ajaxurl, | ||
| 185 | data: { | ||
| 186 | action: 'smush_get_directory_list', | ||
| 187 | list_nonce: $( 'input[name="list_nonce"]' ).val(), | ||
| 188 | }, | ||
| 189 | cache: false, | ||
| 190 | }; | ||
| 191 | |||
| 192 | // Object already defined. | ||
| 193 | if ( Object.entries( self.tree ).length > 0 ) { | ||
| 194 | return; | ||
| 195 | } | ||
| 196 | |||
| 197 | self.tree = createTree( '.wp-smush-list-dialog .content', { | ||
| 198 | autoCollapse: true, // Automatically collapse all siblings, when a node is expanded | ||
| 199 | clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand, 4:activate (dblclick expands) | ||
| 200 | checkbox: true, // Show checkboxes | ||
| 201 | debugLevel: 0, // 0:quiet, 1:errors, 2:warnings, 3:infos, 4:debug | ||
| 202 | selectMode: 3, // 1:single, 2:multi, 3:multi-hier | ||
| 203 | tabindex: '0', // Whole tree behaves as one single control | ||
| 204 | keyboard: true, // Support keyboard navigation | ||
| 205 | quicksearch: true, // Navigate to next node by typing the first letters | ||
| 206 | source: ajaxSettings, | ||
| 207 | lazyLoad: ( event, data ) => { | ||
| 208 | data.result = new Promise( function( resolve, reject ) { | ||
| 209 | ajaxSettings.data.dir = data.node.key; | ||
| 210 | $.ajax( ajaxSettings ) | ||
| 211 | .done( ( response ) => resolve( response ) ) | ||
| 212 | .fail( reject ); | ||
| 213 | } ); | ||
| 214 | }, | ||
| 215 | loadChildren: ( event, data ) => | ||
| 216 | data.node.fixSelection3AfterClick(), // Apply parent's state to new child nodes: | ||
| 217 | select: () => | ||
| 218 | smushButton.prop( | ||
| 219 | 'disabled', | ||
| 220 | ! +self.tree.getSelectedNodes().length | ||
| 221 | ), | ||
| 222 | init: () => smushButton.prop( 'disabled', true ), | ||
| 223 | } ); | ||
| 224 | }, | ||
| 225 | |||
| 226 | /** | ||
| 227 | * Show progress dialog. | ||
| 228 | * | ||
| 229 | * @param {number} items Number of items in the scan. | ||
| 230 | */ | ||
| 231 | showProgressDialog( items ) { | ||
| 232 | // Update items status and show the progress dialog.. | ||
| 233 | $( '.wp-smush-progress-dialog .sui-progress-state-text' ).html( | ||
| 234 | '0/' + items + ' ' + self.wp_smush_msgs.progress_smushed | ||
| 235 | ); | ||
| 236 | |||
| 237 | window.SUI.openModal( | ||
| 238 | 'wp-smush-progress-dialog', | ||
| 239 | 'dialog-close-div', | ||
| 240 | undefined, | ||
| 241 | false | ||
| 242 | ); | ||
| 243 | }, | ||
| 244 | |||
| 245 | /** | ||
| 246 | * Update progress bar during directory smush. | ||
| 247 | * | ||
| 248 | * @param {number} progress Current progress in percent. | ||
| 249 | * @param {boolean} cancel Cancel status. | ||
| 250 | */ | ||
| 251 | updateProgressBar( progress, cancel = false ) { | ||
| 252 | if ( progress > 100 ) { | ||
| 253 | progress = 100; | ||
| 254 | } | ||
| 255 | |||
| 256 | // Update progress bar | ||
| 257 | $( '.sui-progress-block .sui-progress-text span' ).text( | ||
| 258 | progress + '%' | ||
| 259 | ); | ||
| 260 | $( '.sui-progress-block .sui-progress-bar span' ).width( | ||
| 261 | progress + '%' | ||
| 262 | ); | ||
| 263 | |||
| 264 | if ( progress >= 90 ) { | ||
| 265 | $( '.sui-progress-state .sui-progress-state-text' ).text( | ||
| 266 | 'Finalizing...' | ||
| 267 | ); | ||
| 268 | } | ||
| 269 | |||
| 270 | if ( cancel ) { | ||
| 271 | $( '.sui-progress-state .sui-progress-state-text' ).text( | ||
| 272 | 'Cancelling...' | ||
| 273 | ); | ||
| 274 | } | ||
| 275 | }, | ||
| 276 | }; | ||
| 277 | |||
| 278 | WP_Smush.directory.init(); | ||
| 279 | }( jQuery ) ); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | /* global wp_smush_msgs */ | ||
| 4 | |||
| 5 | /** | ||
| 6 | * Helpers functions. | ||
| 7 | * | ||
| 8 | * @since 2.9.0 Moved from admin.js | ||
| 9 | */ | ||
| 10 | ( function() { | ||
| 11 | 'use strict'; | ||
| 12 | |||
| 13 | WP_Smush.helpers = { | ||
| 14 | cacheUpsellErrorCodes: [], | ||
| 15 | init: () => {}, | ||
| 16 | |||
| 17 | /** | ||
| 18 | * Convert bytes to human-readable form. | ||
| 19 | * | ||
| 20 | * @param {number} a Bytes | ||
| 21 | * @param {number} b Number of digits | ||
| 22 | * @return {*} Formatted Bytes | ||
| 23 | */ | ||
| 24 | formatBytes: ( a, b ) => { | ||
| 25 | const thresh = 1024, | ||
| 26 | units = [ 'KB', 'MB', 'GB', 'TB', 'PB' ]; | ||
| 27 | |||
| 28 | if ( Math.abs( a ) < thresh ) { | ||
| 29 | return a + ' B'; | ||
| 30 | } | ||
| 31 | |||
| 32 | let u = -1; | ||
| 33 | |||
| 34 | do { | ||
| 35 | a /= thresh; | ||
| 36 | ++u; | ||
| 37 | } while ( Math.abs( a ) >= thresh && u < units.length - 1 ); | ||
| 38 | |||
| 39 | return a.toFixed( b ) + ' ' + units[ u ]; | ||
| 40 | }, | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Get size from a string. | ||
| 44 | * | ||
| 45 | * @param {string} formattedSize Formatter string | ||
| 46 | * @return {*} Formatted Bytes | ||
| 47 | */ | ||
| 48 | getSizeFromString: ( formattedSize ) => { | ||
| 49 | return formattedSize.replace( /[a-zA-Z]/g, '' ).trim(); | ||
| 50 | }, | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Get type from formatted string. | ||
| 54 | * | ||
| 55 | * @param {string} formattedSize Formatted string | ||
| 56 | * @return {*} Formatted Bytes | ||
| 57 | */ | ||
| 58 | getFormatFromString: ( formattedSize ) => { | ||
| 59 | return formattedSize.replace( /[0-9.]/g, '' ).trim(); | ||
| 60 | }, | ||
| 61 | |||
| 62 | /** | ||
| 63 | * Stackoverflow: http://stackoverflow.com/questions/1726630/formatting-a-number-with-exactly-two-decimals-in-javascript | ||
| 64 | * | ||
| 65 | * @param {number} num | ||
| 66 | * @param {number} decimals | ||
| 67 | * @return {number} Number | ||
| 68 | */ | ||
| 69 | precise_round: ( num, decimals ) => { | ||
| 70 | const sign = num >= 0 ? 1 : -1; | ||
| 71 | // Keep the percentage below 100. | ||
| 72 | num = num > 100 ? 100 : num; | ||
| 73 | return ( | ||
| 74 | Math.round( num * Math.pow( 10, decimals ) + sign * 0.001 ) / | ||
| 75 | Math.pow( 10, decimals ) | ||
| 76 | ); | ||
| 77 | }, | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Displays a floating error message using the #wp-smush-ajax-notice container. | ||
| 81 | * | ||
| 82 | * @since 3.8.0 | ||
| 83 | * | ||
| 84 | * @param {string} message | ||
| 85 | */ | ||
| 86 | showErrorNotice: ( message ) => { | ||
| 87 | if ( 'undefined' === typeof message ) { | ||
| 88 | return; | ||
| 89 | } | ||
| 90 | |||
| 91 | const noticeMessage = `<p>${ message }</p>`, | ||
| 92 | noticeOptions = { | ||
| 93 | type: 'error', | ||
| 94 | icon: 'info', | ||
| 95 | }; | ||
| 96 | |||
| 97 | SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions ); | ||
| 98 | |||
| 99 | const loadingButton = document.querySelector( '.sui-button-onload' ); | ||
| 100 | if ( loadingButton ) { | ||
| 101 | loadingButton.classList.remove( 'sui-button-onload' ); | ||
| 102 | } | ||
| 103 | }, | ||
| 104 | |||
| 105 | /** | ||
| 106 | * Reset settings. | ||
| 107 | * | ||
| 108 | * @since 3.2.0 | ||
| 109 | */ | ||
| 110 | resetSettings: () => { | ||
| 111 | const _nonce = document.getElementById( 'wp_smush_reset' ); | ||
| 112 | const xhr = new XMLHttpRequest(); | ||
| 113 | xhr.open( 'POST', ajaxurl + '?action=reset_settings', true ); | ||
| 114 | xhr.setRequestHeader( | ||
| 115 | 'Content-type', | ||
| 116 | 'application/x-www-form-urlencoded' | ||
| 117 | ); | ||
| 118 | xhr.onload = () => { | ||
| 119 | if ( 200 === xhr.status ) { | ||
| 120 | const res = JSON.parse( xhr.response ); | ||
| 121 | if ( 'undefined' !== typeof res.success && res.success ) { | ||
| 122 | window.location.href = wp_smush_msgs.smush_url; | ||
| 123 | } | ||
| 124 | } else { | ||
| 125 | window.console.log( | ||
| 126 | 'Request failed. Returned status of ' + xhr.status | ||
| 127 | ); | ||
| 128 | } | ||
| 129 | }; | ||
| 130 | xhr.send( '_ajax_nonce=' + _nonce.value ); | ||
| 131 | }, | ||
| 132 | |||
| 133 | /** | ||
| 134 | * Prepare error row. Will only allow to hide errors for WP media attachments (not nextgen). | ||
| 135 | * | ||
| 136 | * @since 1.9.0 | ||
| 137 | * @since 3.12.0 Moved from Smush. | ||
| 138 | * | ||
| 139 | * @param {string} errorMsg Error message. | ||
| 140 | * @param {string} fileName File name. | ||
| 141 | * @param {string} thumbnail Thumbnail for image (if available). | ||
| 142 | * @param {number} id Image ID. | ||
| 143 | * @param {string} type Smush type: media or netxgen. | ||
| 144 | * @param {string} errorCode Error code. | ||
| 145 | * | ||
| 146 | * @return {string} Row with error. | ||
| 147 | */ | ||
| 148 | prepareBulkSmushErrorRow: (errorMsg, fileName, thumbnail, id, type, errorCode) => { | ||
| 149 | const thumbDiv = | ||
| 150 | 'undefined' === typeof thumbnail ? | ||
| 151 | '<i class="sui-icon-photo-picture" aria-hidden="true"></i>' : | ||
| 152 | thumbnail; | ||
| 153 | const editLink = window.wp_smush_msgs.edit_link.replace('{{id}}', id); | ||
| 154 | const fileLink = | ||
| 155 | 'undefined' === fileName || 'undefined' === typeof fileName ? | ||
| 156 | 'undefined' : | ||
| 157 | fileName; | ||
| 158 | |||
| 159 | let tableDiv = | ||
| 160 | '<div class="smush-bulk-error-row" data-error-code="'+ errorCode + '">' + | ||
| 161 | '<div class="smush-bulk-image-data">' + | ||
| 162 | '<div class="smush-bulk-image-title">' + | ||
| 163 | thumbDiv + | ||
| 164 | '<span class="smush-image-name">' + | ||
| 165 | fileLink + | ||
| 166 | '</span>' + | ||
| 167 | '</div>' + | ||
| 168 | '<div class="smush-image-error">' + | ||
| 169 | errorMsg + | ||
| 170 | '</div>' + | ||
| 171 | '</div>'; | ||
| 172 | |||
| 173 | if ('media' === type) { | ||
| 174 | tableDiv = | ||
| 175 | tableDiv + | ||
| 176 | '<div class="smush-bulk-image-actions">' + | ||
| 177 | '<a href="javascript:void(0)" class="sui-tooltip sui-tooltip-constrained sui-tooltip-left smush-ignore-image" data-tooltip="' + | ||
| 178 | window.wp_smush_msgs.error_ignore + | ||
| 179 | '" data-id="' + | ||
| 180 | id + | ||
| 181 | '">' + | ||
| 182 | window.wp_smush_msgs.btn_ignore + | ||
| 183 | '</a>' + | ||
| 184 | '<a class="smush-link-detail" href="' + editLink + '">' + | ||
| 185 | window.wp_smush_msgs.view_detail + | ||
| 186 | '</a>' + | ||
| 187 | '</div>'; | ||
| 188 | } | ||
| 189 | |||
| 190 | tableDiv = tableDiv + '</div>'; | ||
| 191 | |||
| 192 | tableDiv += WP_Smush.helpers.upsellWithError(errorCode); | ||
| 193 | |||
| 194 | return tableDiv; | ||
| 195 | }, | ||
| 196 | /** | ||
| 197 | * Get upsell base on error code. | ||
| 198 | * @param {string} errorCode Error code. | ||
| 199 | * @returns {string} | ||
| 200 | * | ||
| 201 | * Do not use arrow function to use `this`. | ||
| 202 | */ | ||
| 203 | upsellWithError: function (errorCode) { | ||
| 204 | if (!errorCode || !window.wp_smush_msgs['error_' + errorCode] || this.isUpsellRendered( errorCode )) { | ||
| 205 | return ''; | ||
| 206 | } | ||
| 207 | this.cacheRenderedUpsell( errorCode ); | ||
| 208 | return '<div class="smush-bulk-error-row smush-error-upsell">' + | ||
| 209 | '<div class="smush-bulk-image-title">' + | ||
| 210 | '<span class="smush-image-error">' + | ||
| 211 | window.wp_smush_msgs['error_' + errorCode] + | ||
| 212 | '</span>' + | ||
| 213 | '</div></div>'; | ||
| 214 | }, | ||
| 215 | // Do not use arrow function to use `this`. | ||
| 216 | isUpsellRendered: function( errorCode ) { | ||
| 217 | return this.cacheUpsellErrorCodes.includes( errorCode ); | ||
| 218 | }, | ||
| 219 | // Do not use arrow function to use `this`. | ||
| 220 | cacheRenderedUpsell: function ( errorCode ) { | ||
| 221 | this.cacheUpsellErrorCodes.push( errorCode ); | ||
| 222 | }, | ||
| 223 | /** | ||
| 224 | * Get error message from Ajax response or Error. | ||
| 225 | * @param {Object} resp | ||
| 226 | */ | ||
| 227 | getErrorMessage: ( resp ) => { | ||
| 228 | return resp.message || resp.data && resp.data.message || | ||
| 229 | resp.responseJSON && resp.responseJSON.data && resp.responseJSON.data.message || | ||
| 230 | window.wp_smush_msgs.generic_ajax_error || | ||
| 231 | resp.status && 'Request failed. Returned status of ' + resp.status | ||
| 232 | }, | ||
| 233 | |||
| 234 | /** | ||
| 235 | * Displays a floating message from response, | ||
| 236 | * using the #wp-smush-ajax-notice container. | ||
| 237 | * | ||
| 238 | * @param {Object|string} notice | ||
| 239 | * @param {Object} noticeOptions | ||
| 240 | */ | ||
| 241 | showNotice: function( notice, noticeOptions ) { | ||
| 242 | let message; | ||
| 243 | if ( 'object' === typeof notice ) { | ||
| 244 | message = this.getErrorMessage( notice ); | ||
| 245 | } else { | ||
| 246 | message = notice; | ||
| 247 | } | ||
| 248 | |||
| 249 | if ( ! message ) { | ||
| 250 | return; | ||
| 251 | } | ||
| 252 | |||
| 253 | noticeOptions = noticeOptions || {}; | ||
| 254 | noticeOptions = Object.assign({ | ||
| 255 | showdismiss: false, | ||
| 256 | autoclose: true, | ||
| 257 | },noticeOptions); | ||
| 258 | noticeOptions = { | ||
| 259 | type: noticeOptions.type || 'error', | ||
| 260 | icon: noticeOptions.icon || ( 'success' === noticeOptions.type ? 'check-tick' : 'info' ), | ||
| 261 | dismiss: { | ||
| 262 | show: noticeOptions.showdismiss, | ||
| 263 | label: window.wp_smush_msgs.noticeDismiss, | ||
| 264 | tooltip: window.wp_smush_msgs.noticeDismissTooltip, | ||
| 265 | }, | ||
| 266 | autoclose: { | ||
| 267 | show: noticeOptions.autoclose | ||
| 268 | } | ||
| 269 | }; | ||
| 270 | |||
| 271 | const noticeMessage = `<p>${ message }</p>`; | ||
| 272 | |||
| 273 | SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions ); | ||
| 274 | return Promise.resolve( '#wp-smush-ajax-notice' ); | ||
| 275 | }, | ||
| 276 | renderActivationCDNNotice: function( noticeMessage ) { | ||
| 277 | const animatedNotice = document.getElementById('wp-smush-animated-upsell-notice'); | ||
| 278 | if ( animatedNotice ) { | ||
| 279 | return; | ||
| 280 | } | ||
| 281 | const upsellHtml = `<div class="sui-notice sui-notice-info sui-margin-top" id="wp-smush-animated-upsell-notice"> | ||
| 282 | <div class="sui-notice-content"> | ||
| 283 | <div class="sui-notice-message"> | ||
| 284 | <i class="sui-notice-icon sui-icon-info" aria-hidden="true"></i> | ||
| 285 | <p>${noticeMessage}</p> | ||
| 286 | </div> | ||
| 287 | </div> | ||
| 288 | </div>`; | ||
| 289 | document.querySelector( '#smush-box-bulk .wp-smush-bulk-wrapper' ).outerHTML += upsellHtml; | ||
| 290 | } | ||
| 291 | }; | ||
| 292 | |||
| 293 | WP_Smush.helpers.init(); | ||
| 294 | }() ); |
| 1 | /* global ajaxurl */ | ||
| 2 | /* global wp_smush_msgs */ | ||
| 3 | |||
| 4 | ( function( $ ) { | ||
| 5 | 'use strict'; | ||
| 6 | |||
| 7 | const s3alert = $( '#wp-smush-s3support-alert' ); | ||
| 8 | |||
| 9 | /** | ||
| 10 | * S3 support alert. | ||
| 11 | * | ||
| 12 | * @since 3.6.2 Moved from class-s3.php | ||
| 13 | */ | ||
| 14 | if ( s3alert.length ) { | ||
| 15 | const noticeOptions = { | ||
| 16 | type: 'warning', | ||
| 17 | icon: 'info', | ||
| 18 | dismiss: { | ||
| 19 | show: true, | ||
| 20 | label: wp_smush_msgs.noticeDismiss, | ||
| 21 | tooltip: wp_smush_msgs.noticeDismissTooltip, | ||
| 22 | }, | ||
| 23 | }; | ||
| 24 | |||
| 25 | window.SUI.openNotice( | ||
| 26 | 'wp-smush-s3support-alert', | ||
| 27 | s3alert.data( 'message' ), | ||
| 28 | noticeOptions | ||
| 29 | ); | ||
| 30 | } | ||
| 31 | |||
| 32 | // Dismiss S3 support alert. | ||
| 33 | s3alert.on( 'click', 'button', () => { | ||
| 34 | $.post( ajaxurl, | ||
| 35 | { | ||
| 36 | action: 'dismiss_s3support_alert', | ||
| 37 | _ajax_nonce: window.wp_smush_msgs.nonce, | ||
| 38 | } | ||
| 39 | ); | ||
| 40 | } ); | ||
| 41 | |||
| 42 | // Remove API message. | ||
| 43 | $( '#wp-smush-api-message button.sui-button-icon' ).on( 'click', function( e ) { | ||
| 44 | e.preventDefault(); | ||
| 45 | const notice = $( '#wp-smush-api-message' ); | ||
| 46 | notice.slideUp( 'slow', function() { | ||
| 47 | notice.remove(); | ||
| 48 | } ); | ||
| 49 | $.post( ajaxurl, | ||
| 50 | { | ||
| 51 | action: 'hide_api_message', | ||
| 52 | _ajax_nonce: window.wp_smush_msgs.nonce, | ||
| 53 | } | ||
| 54 | ); | ||
| 55 | } ); | ||
| 56 | |||
| 57 | // Hide the notice after a CTA button was clicked | ||
| 58 | function removeNotice( e ) { | ||
| 59 | const $notice = $( e.currentTarget ).closest( '.smush-notice' ); | ||
| 60 | $notice.fadeTo( 100, 0, () => | ||
| 61 | $notice.slideUp( 100, () => $notice.remove() ) | ||
| 62 | ); | ||
| 63 | } | ||
| 64 | |||
| 65 | // Only used for the Dashboard notification for now. | ||
| 66 | $( '.smush-notice .smush-notice-act' ).on( 'click', ( e ) => { | ||
| 67 | removeNotice( e ); | ||
| 68 | } ); | ||
| 69 | |||
| 70 | // Dismiss the update notice. | ||
| 71 | $( '.wp-smush-update-info' ).on( 'click', '.notice-dismiss', ( e ) => { | ||
| 72 | e.preventDefault(); | ||
| 73 | removeNotice( e ); | ||
| 74 | $.post( ajaxurl, | ||
| 75 | { | ||
| 76 | action: 'dismiss_update_info', | ||
| 77 | _ajax_nonce: window.wp_smush_msgs.nonce, | ||
| 78 | } | ||
| 79 | ); | ||
| 80 | } ); | ||
| 81 | }( jQuery ) ); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Modals JavaScript code. | ||
| 6 | */ | ||
| 7 | ( function() { | ||
| 8 | 'use strict'; | ||
| 9 | |||
| 10 | /** | ||
| 11 | * Onboarding modal. | ||
| 12 | * | ||
| 13 | * @since 3.1 | ||
| 14 | */ | ||
| 15 | WP_Smush.onboarding = { | ||
| 16 | membership: 'free', // Assume free by default. | ||
| 17 | onboardingModal: document.getElementById( 'smush-onboarding-dialog' ), | ||
| 18 | scanFilesModal: document.getElementById( 'checking-files-dialog' ), | ||
| 19 | first_slide: 'usage', | ||
| 20 | settings: { | ||
| 21 | first: true, | ||
| 22 | last: false, | ||
| 23 | slide: 'usage', | ||
| 24 | value: false, | ||
| 25 | }, | ||
| 26 | selection: { | ||
| 27 | usage: false, | ||
| 28 | auto: true, | ||
| 29 | lossy: true, | ||
| 30 | strip_exif: true, | ||
| 31 | original: false, | ||
| 32 | lazy_load: true, | ||
| 33 | }, | ||
| 34 | contentContainer: document.getElementById( 'smush-onboarding-content' ), | ||
| 35 | onboardingSlides: [ | ||
| 36 | 'usage', | ||
| 37 | 'auto', | ||
| 38 | 'lossy', | ||
| 39 | 'strip_exif', | ||
| 40 | 'original', | ||
| 41 | 'lazy_load', | ||
| 42 | ], | ||
| 43 | touchX: null, | ||
| 44 | touchY: null, | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Init module. | ||
| 48 | */ | ||
| 49 | init() { | ||
| 50 | if ( ! this.onboardingModal ) { | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | |||
| 54 | const dialog = document.getElementById( 'smush-onboarding' ); | ||
| 55 | |||
| 56 | this.membership = dialog.dataset.type; | ||
| 57 | |||
| 58 | if ( 'pro' !== this.membership ) { | ||
| 59 | this.onboardingSlides = [ | ||
| 60 | 'usage', | ||
| 61 | 'auto', | ||
| 62 | 'lossy', | ||
| 63 | 'strip_exif', | ||
| 64 | 'lazy_load', | ||
| 65 | ]; | ||
| 66 | } | ||
| 67 | |||
| 68 | if ( 'false' === dialog.dataset.tracking ) { | ||
| 69 | this.onboardingSlides.pop(); | ||
| 70 | } | ||
| 71 | |||
| 72 | this.renderTemplate(); | ||
| 73 | |||
| 74 | // Skip setup. | ||
| 75 | const skipButton = this.onboardingModal.querySelector( | ||
| 76 | '.smush-onboarding-skip-link' | ||
| 77 | ); | ||
| 78 | if ( skipButton ) { | ||
| 79 | skipButton.addEventListener( 'click', this.skipSetup ); | ||
| 80 | } | ||
| 81 | |||
| 82 | // Show the modal. | ||
| 83 | window.SUI.openModal( | ||
| 84 | 'smush-onboarding-dialog', | ||
| 85 | 'checking-files-dialog', | ||
| 86 | undefined, | ||
| 87 | false | ||
| 88 | ); | ||
| 89 | }, | ||
| 90 | |||
| 91 | /** | ||
| 92 | * Get swipe coordinates. | ||
| 93 | * | ||
| 94 | * @param {Object} e | ||
| 95 | */ | ||
| 96 | handleTouchStart( e ) { | ||
| 97 | const firstTouch = e.touches[ 0 ]; | ||
| 98 | this.touchX = firstTouch.clientX; | ||
| 99 | this.touchY = firstTouch.clientY; | ||
| 100 | }, | ||
| 101 | |||
| 102 | /** | ||
| 103 | * Process swipe left/right. | ||
| 104 | * | ||
| 105 | * @param {Object} e | ||
| 106 | */ | ||
| 107 | handleTouchMove( e ) { | ||
| 108 | if ( ! this.touchX || ! this.touchY ) { | ||
| 109 | return; | ||
| 110 | } | ||
| 111 | |||
| 112 | const xUp = e.touches[ 0 ].clientX, | ||
| 113 | yUp = e.touches[ 0 ].clientY, | ||
| 114 | xDiff = this.touchX - xUp, | ||
| 115 | yDiff = this.touchY - yUp; | ||
| 116 | |||
| 117 | if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) { | ||
| 118 | if ( xDiff > 0 ) { | ||
| 119 | if ( false === WP_Smush.onboarding.settings.last ) { | ||
| 120 | WP_Smush.onboarding.next( null, 'next' ); | ||
| 121 | } | ||
| 122 | } else if ( false === WP_Smush.onboarding.settings.first ) { | ||
| 123 | WP_Smush.onboarding.next( null, 'prev' ); | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | this.touchX = null; | ||
| 128 | this.touchY = null; | ||
| 129 | }, | ||
| 130 | |||
| 131 | /** | ||
| 132 | * Update the template, register new listeners. | ||
| 133 | * | ||
| 134 | * @param {string} directionClass Accepts: fadeInRight, fadeInLeft, none. | ||
| 135 | */ | ||
| 136 | renderTemplate( directionClass = 'none' ) { | ||
| 137 | // Grab the selected value. | ||
| 138 | const input = this.onboardingModal.querySelector( | ||
| 139 | 'input[type="checkbox"]' | ||
| 140 | ); | ||
| 141 | if ( input ) { | ||
| 142 | this.selection[ input.id ] = input.checked; | ||
| 143 | } | ||
| 144 | |||
| 145 | const template = WP_Smush.onboarding.template( 'smush-onboarding' ); | ||
| 146 | const content = template( this.settings ); | ||
| 147 | |||
| 148 | if ( content ) { | ||
| 149 | this.contentContainer.innerHTML = content; | ||
| 150 | |||
| 151 | if ( 'none' === directionClass ) { | ||
| 152 | this.contentContainer.classList.add( 'loaded' ); | ||
| 153 | } else { | ||
| 154 | this.contentContainer.classList.remove( 'loaded' ); | ||
| 155 | this.contentContainer.classList.add( directionClass ); | ||
| 156 | setTimeout( () => { | ||
| 157 | this.contentContainer.classList.add( 'loaded' ); | ||
| 158 | this.contentContainer.classList.remove( | ||
| 159 | directionClass | ||
| 160 | ); | ||
| 161 | }, 600 ); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | this.onboardingModal.addEventListener( | ||
| 166 | 'touchstart', | ||
| 167 | this.handleTouchStart, | ||
| 168 | false | ||
| 169 | ); | ||
| 170 | this.onboardingModal.addEventListener( | ||
| 171 | 'touchmove', | ||
| 172 | this.handleTouchMove, | ||
| 173 | false | ||
| 174 | ); | ||
| 175 | |||
| 176 | this.bindSubmit(); | ||
| 177 | }, | ||
| 178 | |||
| 179 | /** | ||
| 180 | * Catch "Finish setup wizard" button click. | ||
| 181 | */ | ||
| 182 | bindSubmit() { | ||
| 183 | const submitButton = this.onboardingModal.querySelector( | ||
| 184 | 'button[type="submit"]' | ||
| 185 | ); | ||
| 186 | const self = this; | ||
| 187 | |||
| 188 | if ( submitButton ) { | ||
| 189 | submitButton.addEventListener( 'click', function( e ) { | ||
| 190 | e.preventDefault(); | ||
| 191 | |||
| 192 | // Because we are not rendering the template, we need to update the last element value. | ||
| 193 | const input = self.onboardingModal.querySelector( | ||
| 194 | 'input[type="checkbox"]' | ||
| 195 | ); | ||
| 196 | if ( input ) { | ||
| 197 | self.selection[ input.id ] = input.checked; | ||
| 198 | } | ||
| 199 | |||
| 200 | const _nonce = document.getElementById( | ||
| 201 | 'smush_quick_setup_nonce' | ||
| 202 | ); | ||
| 203 | |||
| 204 | const xhr = new XMLHttpRequest(); | ||
| 205 | xhr.open( 'POST', ajaxurl + '?action=smush_setup', true ); | ||
| 206 | xhr.setRequestHeader( | ||
| 207 | 'Content-type', | ||
| 208 | 'application/x-www-form-urlencoded' | ||
| 209 | ); | ||
| 210 | xhr.onload = () => { | ||
| 211 | if ( 200 === xhr.status ) { | ||
| 212 | WP_Smush.onboarding.showScanDialog(); | ||
| 213 | } else { | ||
| 214 | window.console.log( | ||
| 215 | 'Request failed. Returned status of ' + | ||
| 216 | xhr.status | ||
| 217 | ); | ||
| 218 | } | ||
| 219 | }; | ||
| 220 | xhr.send( | ||
| 221 | 'smush_settings=' + | ||
| 222 | JSON.stringify( self.selection ) + | ||
| 223 | '&_ajax_nonce=' + | ||
| 224 | _nonce.value | ||
| 225 | ); | ||
| 226 | } ); | ||
| 227 | } | ||
| 228 | }, | ||
| 229 | |||
| 230 | /** | ||
| 231 | * Handle navigation. | ||
| 232 | * | ||
| 233 | * @param {Object} e | ||
| 234 | * @param {null|string} whereTo | ||
| 235 | */ | ||
| 236 | next( e, whereTo = null ) { | ||
| 237 | const index = this.onboardingSlides.indexOf( this.settings.slide ); | ||
| 238 | let newIndex = 0; | ||
| 239 | |||
| 240 | if ( ! whereTo ) { | ||
| 241 | newIndex = | ||
| 242 | null !== e && e.classList.contains( 'next' ) | ||
| 243 | ? index + 1 | ||
| 244 | : index - 1; | ||
| 245 | } else { | ||
| 246 | newIndex = 'next' === whereTo ? index + 1 : index - 1; | ||
| 247 | } | ||
| 248 | |||
| 249 | const directionClass = | ||
| 250 | null !== e && e.classList.contains( 'next' ) | ||
| 251 | ? 'fadeInRight' | ||
| 252 | : 'fadeInLeft'; | ||
| 253 | |||
| 254 | this.settings = { | ||
| 255 | first: 0 === newIndex, | ||
| 256 | last: newIndex + 1 === this.onboardingSlides.length, // length !== index | ||
| 257 | slide: this.onboardingSlides[ newIndex ], | ||
| 258 | value: this.selection[ this.onboardingSlides[ newIndex ] ], | ||
| 259 | }; | ||
| 260 | |||
| 261 | this.renderTemplate( directionClass ); | ||
| 262 | }, | ||
| 263 | |||
| 264 | /** | ||
| 265 | * Handle circle navigation. | ||
| 266 | * | ||
| 267 | * @param {string} target | ||
| 268 | */ | ||
| 269 | goTo( target ) { | ||
| 270 | const newIndex = this.onboardingSlides.indexOf( target ); | ||
| 271 | |||
| 272 | this.settings = { | ||
| 273 | first: 0 === newIndex, | ||
| 274 | last: newIndex + 1 === this.onboardingSlides.length, // length !== index | ||
| 275 | slide: target, | ||
| 276 | value: this.selection[ target ], | ||
| 277 | }; | ||
| 278 | |||
| 279 | this.renderTemplate(); | ||
| 280 | }, | ||
| 281 | |||
| 282 | /** | ||
| 283 | * Skip onboarding experience. | ||
| 284 | */ | ||
| 285 | skipSetup: () => { | ||
| 286 | const _nonce = document.getElementById( 'smush_quick_setup_nonce' ); | ||
| 287 | |||
| 288 | const xhr = new XMLHttpRequest(); | ||
| 289 | xhr.open( | ||
| 290 | 'POST', | ||
| 291 | ajaxurl + '?action=skip_smush_setup&_ajax_nonce=' + _nonce.value | ||
| 292 | ); | ||
| 293 | xhr.onload = () => { | ||
| 294 | if ( 200 === xhr.status ) { | ||
| 295 | WP_Smush.onboarding.showScanDialog(); | ||
| 296 | } else { | ||
| 297 | window.console.log( | ||
| 298 | 'Request failed. Returned status of ' + xhr.status | ||
| 299 | ); | ||
| 300 | } | ||
| 301 | }; | ||
| 302 | xhr.send(); | ||
| 303 | }, | ||
| 304 | |||
| 305 | /** | ||
| 306 | * Show checking files dialog. | ||
| 307 | */ | ||
| 308 | showScanDialog() { | ||
| 309 | window.SUI.closeModal(); | ||
| 310 | // Do not need to re-check images if we are in bulk smush page. | ||
| 311 | if ( window.location.search.indexOf('page=smush-bulk') > -1 ) { | ||
| 312 | return; | ||
| 313 | } | ||
| 314 | window.SUI.openModal( | ||
| 315 | 'checking-files-dialog', | ||
| 316 | 'wpbody-content', | ||
| 317 | undefined, | ||
| 318 | false | ||
| 319 | ); | ||
| 320 | |||
| 321 | const nonce = document.getElementById( 'wp_smush_options_nonce' ); | ||
| 322 | |||
| 323 | setTimeout( () => { | ||
| 324 | const xhr = new XMLHttpRequest(); | ||
| 325 | xhr.open( 'POST', ajaxurl + '?action=scan_for_resmush', true ); | ||
| 326 | xhr.setRequestHeader( | ||
| 327 | 'Content-type', | ||
| 328 | 'application/x-www-form-urlencoded' | ||
| 329 | ); | ||
| 330 | xhr.onload = () => { | ||
| 331 | const elem = document.querySelector( | ||
| 332 | '#smush-onboarding-dialog' | ||
| 333 | ); | ||
| 334 | elem.parentNode.removeChild( elem ); | ||
| 335 | |||
| 336 | if ( 200 === xhr.status ) { | ||
| 337 | setTimeout( function() { | ||
| 338 | window.location.search = 'page=smush-bulk'; | ||
| 339 | }, 1000 ); | ||
| 340 | } else { | ||
| 341 | window.console.log( | ||
| 342 | 'Request failed. Returned status of ' + xhr.status | ||
| 343 | ); | ||
| 344 | } | ||
| 345 | }; | ||
| 346 | xhr.send( | ||
| 347 | 'type=media&get_ui=false&process_settings=false&wp_smush_options_nonce=' + | ||
| 348 | nonce.value | ||
| 349 | ); | ||
| 350 | }, 3000 ); | ||
| 351 | }, | ||
| 352 | |||
| 353 | /** | ||
| 354 | * Hide new features modal. | ||
| 355 | * | ||
| 356 | * @param {string} redirectUrl Redirect url after dismissing the new feature modal. | ||
| 357 | * @since 3.7.0 | ||
| 358 | * @since 3.12.2 Add a new parameter redirectUrl | ||
| 359 | */ | ||
| 360 | hideUpgradeModal: ( redirectUrl ) => { | ||
| 361 | window.SUI.closeModal( 'smush-updated-dialog' ); | ||
| 362 | const xhr = new XMLHttpRequest(); | ||
| 363 | xhr.open( 'POST', ajaxurl + '?action=hide_new_features&_ajax_nonce=' + window.wp_smush_msgs.nonce ); | ||
| 364 | xhr.onload = () => { | ||
| 365 | if ( 200 === xhr.status ) { | ||
| 366 | if ( redirectUrl ) { | ||
| 367 | window.location.href = redirectUrl; | ||
| 368 | } | ||
| 369 | } else { | ||
| 370 | window.console.log( | ||
| 371 | 'Request failed. Returned status of ' + xhr.status | ||
| 372 | ); | ||
| 373 | } | ||
| 374 | } | ||
| 375 | xhr.send(); | ||
| 376 | }, | ||
| 377 | }; | ||
| 378 | |||
| 379 | /** | ||
| 380 | * Template function (underscores based). | ||
| 381 | * | ||
| 382 | * @type {Function} | ||
| 383 | */ | ||
| 384 | WP_Smush.onboarding.template = _.memoize( ( id ) => { | ||
| 385 | let compiled; | ||
| 386 | const options = { | ||
| 387 | evaluate: /<#([\s\S]+?)#>/g, | ||
| 388 | interpolate: /{{{([\s\S]+?)}}}/g, | ||
| 389 | escape: /{{([^}]+?)}}(?!})/g, | ||
| 390 | variable: 'data', | ||
| 391 | }; | ||
| 392 | |||
| 393 | return ( data ) => { | ||
| 394 | _.templateSettings = options; | ||
| 395 | compiled = | ||
| 396 | compiled || | ||
| 397 | _.template( document.getElementById( id ).innerHTML ); | ||
| 398 | data.first_slide = WP_Smush.onboarding.first_slide; | ||
| 399 | return compiled( data ); | ||
| 400 | }; | ||
| 401 | } ); | ||
| 402 | |||
| 403 | window.addEventListener( 'load', () => WP_Smush.onboarding.init() ); | ||
| 404 | }() ); |
| 1 | /** | ||
| 2 | * Shared UI JS libraries. Use only what we need to keep the vendor file size smaller. | ||
| 3 | * | ||
| 4 | * @package | ||
| 5 | */ | ||
| 6 | require( '@wpmudev/shared-ui/dist/js/_src/code-snippet' ); | ||
| 7 | require( '@wpmudev/shared-ui/dist/js/_src/modal-dialog' ); | ||
| 8 | require( '@wpmudev/shared-ui/dist/js/_src/notifications' ); | ||
| 9 | require( '@wpmudev/shared-ui/dist/js/_src/select2.full' ); | ||
| 10 | require( '@wpmudev/shared-ui/dist/js/_src/select2' ); | ||
| 11 | require( '@wpmudev/shared-ui/dist/js/_src/tabs' ); | ||
| 12 | require( '@wpmudev/shared-ui/dist/js/_src/upload' ); // Used on lazy load page (since 3.2.2). | ||
| 13 | require( '@wpmudev/shared-ui/dist/js/_src/reviews' ); |
| 1 | /** | ||
| 2 | * BLOCK: extend image block | ||
| 3 | */ | ||
| 4 | const { createHigherOrderComponent } = wp.compose, | ||
| 5 | { Fragment } = wp.element, | ||
| 6 | { InspectorControls } = wp.blockEditor, | ||
| 7 | { PanelBody } = wp.components; | ||
| 8 | |||
| 9 | /** | ||
| 10 | * Transform bytes to human readable format. | ||
| 11 | * | ||
| 12 | * @param {number} bytes | ||
| 13 | * @return {string} Readable size string. | ||
| 14 | */ | ||
| 15 | function humanFileSize( bytes ) { | ||
| 16 | const thresh = 1024, | ||
| 17 | units = [ 'kB', 'MB', 'GB', 'TB' ]; | ||
| 18 | |||
| 19 | if ( Math.abs( bytes ) < thresh ) { | ||
| 20 | return bytes + ' B'; | ||
| 21 | } | ||
| 22 | |||
| 23 | let u = -1; | ||
| 24 | do { | ||
| 25 | bytes /= thresh; | ||
| 26 | ++u; | ||
| 27 | } while ( Math.abs( bytes ) >= thresh && u < units.length - 1 ); | ||
| 28 | |||
| 29 | return bytes.toFixed( 1 ) + ' ' + units[ u ]; | ||
| 30 | } | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Generate Smush stats table. | ||
| 34 | * | ||
| 35 | * @param {number} id | ||
| 36 | * @param {Object} stats | ||
| 37 | * @return {*} Smush stats. | ||
| 38 | */ | ||
| 39 | export function smushStats( id, stats ) { | ||
| 40 | if ( 'undefined' === typeof stats ) { | ||
| 41 | return window.smush_vars.strings.gb.select_image; | ||
| 42 | } else if ( 'string' === typeof stats ) { | ||
| 43 | return stats; | ||
| 44 | } | ||
| 45 | |||
| 46 | return ( | ||
| 47 | <div | ||
| 48 | id="smush-stats" | ||
| 49 | className="sui-smush-media smush-stats-wrapper hidden" | ||
| 50 | style={ { display: 'block' } } | ||
| 51 | > | ||
| 52 | <table className="wp-smush-stats-holder"> | ||
| 53 | <thead> | ||
| 54 | <tr> | ||
| 55 | <th className="smush-stats-header"> | ||
| 56 | { window.smush_vars.strings.gb.size } | ||
| 57 | </th> | ||
| 58 | <th className="smush-stats-header"> | ||
| 59 | { window.smush_vars.strings.gb.savings } | ||
| 60 | </th> | ||
| 61 | </tr> | ||
| 62 | </thead> | ||
| 63 | <tbody> | ||
| 64 | { Object.keys( stats.sizes ) | ||
| 65 | .filter( ( item ) => 0 < stats.sizes[ item ].percent ) | ||
| 66 | .map( ( item, i ) => ( | ||
| 67 | <tr key={ i }> | ||
| 68 | <td>{ item.toUpperCase() }</td> | ||
| 69 | <td> | ||
| 70 | { humanFileSize( | ||
| 71 | stats.sizes[ item ].bytes | ||
| 72 | ) }{ ' ' } | ||
| 73 | ( { stats.sizes[ item ].percent }% ) | ||
| 74 | </td> | ||
| 75 | </tr> | ||
| 76 | ) ) } | ||
| 77 | </tbody> | ||
| 78 | </table> | ||
| 79 | </div> | ||
| 80 | ); | ||
| 81 | } | ||
| 82 | |||
| 83 | /** | ||
| 84 | * Fetch image data. If image is Smushing, update in 3 seconds. | ||
| 85 | * | ||
| 86 | * TODO: this could be optimized not to query so much. | ||
| 87 | * | ||
| 88 | * @param {Object} props | ||
| 89 | */ | ||
| 90 | export function fetchProps( props ) { | ||
| 91 | const image = new wp.api.models.Media( { id: props.attributes.id } ), | ||
| 92 | smushData = props.attributes.smush; | ||
| 93 | |||
| 94 | image.fetch( { attribute: 'smush' } ).done( function( img ) { | ||
| 95 | if ( 'string' === typeof img.smush ) { | ||
| 96 | props.setAttributes( { smush: img.smush } ); | ||
| 97 | //setTimeout( () => fetch( props ), 3000 ); | ||
| 98 | } else if ( | ||
| 99 | 'undefined' !== typeof img.smush && | ||
| 100 | ( 'undefined' === typeof smushData || | ||
| 101 | JSON.stringify( smushData ) !== JSON.stringify( img.smush ) ) | ||
| 102 | ) { | ||
| 103 | props.setAttributes( { smush: img.smush } ); | ||
| 104 | } | ||
| 105 | } ); | ||
| 106 | } | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Modify the block’s edit component. | ||
| 110 | * Receives the original block BlockEdit component and returns a new wrapped component. | ||
| 111 | */ | ||
| 112 | const smushStatsControl = createHigherOrderComponent( ( BlockEdit ) => { | ||
| 113 | return ( props ) => { | ||
| 114 | // If not image block or not selected, return unmodified block. | ||
| 115 | if ( | ||
| 116 | 'core/image' !== props.name || | ||
| 117 | ! props.isSelected || | ||
| 118 | 'undefined' === typeof props.attributes.id | ||
| 119 | ) { | ||
| 120 | return ( | ||
| 121 | <Fragment> | ||
| 122 | <BlockEdit { ...props } /> | ||
| 123 | </Fragment> | ||
| 124 | ); | ||
| 125 | } | ||
| 126 | |||
| 127 | const smushData = props.attributes.smush; | ||
| 128 | fetchProps( props ); | ||
| 129 | |||
| 130 | return ( | ||
| 131 | <Fragment> | ||
| 132 | <BlockEdit { ...props } /> | ||
| 133 | <InspectorControls> | ||
| 134 | <PanelBody title={ window.smush_vars.strings.gb.stats }> | ||
| 135 | { smushStats( props.attributes.id, smushData ) } | ||
| 136 | </PanelBody> | ||
| 137 | </InspectorControls> | ||
| 138 | </Fragment> | ||
| 139 | ); | ||
| 140 | }; | ||
| 141 | }, 'withInspectorControl' ); | ||
| 142 | |||
| 143 | wp.hooks.addFilter( | ||
| 144 | 'editor.BlockEdit', | ||
| 145 | 'wp-smush/smush-data-control', | ||
| 146 | smushStatsControl | ||
| 147 | ); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * CDN functionality. | ||
| 6 | * | ||
| 7 | * @since 3.0 | ||
| 8 | */ | ||
| 9 | ( function() { | ||
| 10 | 'use strict'; | ||
| 11 | |||
| 12 | WP_Smush.CDN = { | ||
| 13 | cdnEnableButton: document.getElementById( 'smush-enable-cdn' ), | ||
| 14 | cdnDisableButton: document.getElementById( 'smush-cancel-cdn' ), | ||
| 15 | cdnStatsBox: document.querySelector( '.smush-cdn-stats' ), | ||
| 16 | |||
| 17 | init() { | ||
| 18 | /** | ||
| 19 | * Handle "Get Started" button click on disabled CDN page. | ||
| 20 | */ | ||
| 21 | if ( this.cdnEnableButton ) { | ||
| 22 | this.cdnEnableButton.addEventListener( 'click', ( e ) => { | ||
| 23 | e.preventDefault(); | ||
| 24 | e.currentTarget.classList.add( 'sui-button-onload' ); | ||
| 25 | this.toggle_cdn( true ); | ||
| 26 | } ); | ||
| 27 | } | ||
| 28 | |||
| 29 | /** | ||
| 30 | * Handle "Deactivate' button click on CDN page. | ||
| 31 | */ | ||
| 32 | if ( this.cdnDisableButton ) { | ||
| 33 | this.cdnDisableButton.addEventListener( 'click', ( e ) => { | ||
| 34 | e.preventDefault(); | ||
| 35 | e.currentTarget.classList.add( 'sui-button-onload' ); | ||
| 36 | |||
| 37 | this.toggle_cdn( false ); | ||
| 38 | } ); | ||
| 39 | } | ||
| 40 | |||
| 41 | this.updateStatsBox(); | ||
| 42 | }, | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Toggle CDN. | ||
| 46 | * | ||
| 47 | * @since 3.0 | ||
| 48 | * | ||
| 49 | * @param {boolean} enable | ||
| 50 | */ | ||
| 51 | toggle_cdn( enable ) { | ||
| 52 | const nonceField = document.getElementsByName( | ||
| 53 | 'wp_smush_options_nonce' | ||
| 54 | ); | ||
| 55 | |||
| 56 | const xhr = new XMLHttpRequest(); | ||
| 57 | xhr.open( 'POST', ajaxurl + '?action=smush_toggle_cdn', true ); | ||
| 58 | xhr.setRequestHeader( | ||
| 59 | 'Content-type', | ||
| 60 | 'application/x-www-form-urlencoded' | ||
| 61 | ); | ||
| 62 | xhr.onload = () => { | ||
| 63 | if ( 200 === xhr.status ) { | ||
| 64 | const res = JSON.parse( xhr.response ); | ||
| 65 | if ( 'undefined' !== typeof res.success && res.success ) { | ||
| 66 | window.location.search = 'page=smush-cdn'; | ||
| 67 | } else if ( 'undefined' !== typeof res.data.message ) { | ||
| 68 | WP_Smush.helpers.showErrorNotice( res.data.message ); | ||
| 69 | } | ||
| 70 | } else { | ||
| 71 | WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status ); | ||
| 72 | } | ||
| 73 | }; | ||
| 74 | xhr.send( | ||
| 75 | 'param=' + enable + '&_ajax_nonce=' + nonceField[ 0 ].value | ||
| 76 | ); | ||
| 77 | }, | ||
| 78 | |||
| 79 | /** | ||
| 80 | * Update the CDN stats box in summary meta box. Only fetch new data when on CDN page. | ||
| 81 | * | ||
| 82 | * @since 3.0 | ||
| 83 | */ | ||
| 84 | updateStatsBox() { | ||
| 85 | if ( | ||
| 86 | 'undefined' === typeof this.cdnStatsBox || | ||
| 87 | ! this.cdnStatsBox | ||
| 88 | ) { | ||
| 89 | return; | ||
| 90 | } | ||
| 91 | |||
| 92 | // Only fetch the new stats, when user is on CDN page. | ||
| 93 | if ( ! window.location.search.includes( 'page=smush-cdn' ) ) { | ||
| 94 | return; | ||
| 95 | } | ||
| 96 | |||
| 97 | this.toggleElements(); | ||
| 98 | |||
| 99 | const xhr = new XMLHttpRequest(); | ||
| 100 | xhr.open( 'POST', ajaxurl + '?action=get_cdn_stats', true ); | ||
| 101 | xhr.onload = () => { | ||
| 102 | if ( 200 === xhr.status ) { | ||
| 103 | const res = JSON.parse( xhr.response ); | ||
| 104 | if ( 'undefined' !== typeof res.success && res.success ) { | ||
| 105 | this.toggleElements(); | ||
| 106 | } else if ( 'undefined' !== typeof res.data.message ) { | ||
| 107 | WP_Smush.helpers.showErrorNotice( res.data.message ); | ||
| 108 | } | ||
| 109 | } else { | ||
| 110 | WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status ); | ||
| 111 | } | ||
| 112 | }; | ||
| 113 | xhr.send(); | ||
| 114 | }, | ||
| 115 | |||
| 116 | /** | ||
| 117 | * Show/hide elements during status update in the updateStatsBox() | ||
| 118 | * | ||
| 119 | * @since 3.1 Moved out from updateStatsBox() | ||
| 120 | */ | ||
| 121 | toggleElements() { | ||
| 122 | const spinner = this.cdnStatsBox.querySelector( | ||
| 123 | '.sui-icon-loader' | ||
| 124 | ); | ||
| 125 | const elements = this.cdnStatsBox.querySelectorAll( | ||
| 126 | '.wp-smush-stats > :not(.sui-icon-loader)' | ||
| 127 | ); | ||
| 128 | |||
| 129 | for ( let i = 0; i < elements.length; i++ ) { | ||
| 130 | elements[ i ].classList.toggle( 'sui-hidden' ); | ||
| 131 | } | ||
| 132 | |||
| 133 | spinner.classList.toggle( 'sui-hidden' ); | ||
| 134 | }, | ||
| 135 | }; | ||
| 136 | |||
| 137 | WP_Smush.CDN.init(); | ||
| 138 | } )(); |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Directory scanner module that will Smush images in the Directory Smush modal. | ||
| 6 | * | ||
| 7 | * @since 2.8.1 | ||
| 8 | * | ||
| 9 | * @param {string|number} totalSteps | ||
| 10 | * @param {string|number} currentStep | ||
| 11 | * @return {Object} Scan object. | ||
| 12 | * @class | ||
| 13 | */ | ||
| 14 | const DirectoryScanner = ( totalSteps, currentStep ) => { | ||
| 15 | totalSteps = parseInt( totalSteps ); | ||
| 16 | currentStep = parseInt( currentStep ); | ||
| 17 | |||
| 18 | let cancelling = false, | ||
| 19 | failedItems = 0, | ||
| 20 | skippedItems = 0; | ||
| 21 | |||
| 22 | const obj = { | ||
| 23 | scan() { | ||
| 24 | const remainingSteps = totalSteps - currentStep; | ||
| 25 | if ( currentStep !== 0 ) { | ||
| 26 | // Scan started on a previous page load. | ||
| 27 | step( remainingSteps ).fail( this.showScanError ); | ||
| 28 | } else { | ||
| 29 | jQuery | ||
| 30 | .post( ajaxurl, { | ||
| 31 | action: 'directory_smush_start', | ||
| 32 | _ajax_nonce: window.wp_smush_msgs.nonce | ||
| 33 | }, () => | ||
| 34 | step( remainingSteps ).fail( this.showScanError ) | ||
| 35 | ) | ||
| 36 | .fail( this.showScanError ); | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | |||
| 40 | cancel() { | ||
| 41 | cancelling = true; | ||
| 42 | return jQuery.post( ajaxurl, { | ||
| 43 | action: 'directory_smush_cancel', | ||
| 44 | _ajax_nonce: window.wp_smush_msgs.nonce | ||
| 45 | } ); | ||
| 46 | }, | ||
| 47 | |||
| 48 | getProgress() { | ||
| 49 | if ( cancelling ) { | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | // O M G ... Logic at it's finest! | ||
| 53 | const remainingSteps = totalSteps - currentStep; | ||
| 54 | return Math.min( | ||
| 55 | Math.round( | ||
| 56 | ( parseInt( totalSteps - remainingSteps ) * 100 ) / | ||
| 57 | totalSteps | ||
| 58 | ), | ||
| 59 | 99 | ||
| 60 | ); | ||
| 61 | }, | ||
| 62 | |||
| 63 | onFinishStep( progress ) { | ||
| 64 | jQuery( '.wp-smush-progress-dialog .sui-progress-state-text' ).html( | ||
| 65 | currentStep - | ||
| 66 | failedItems + | ||
| 67 | '/' + | ||
| 68 | totalSteps + | ||
| 69 | ' ' + | ||
| 70 | window.wp_smush_msgs.progress_smushed | ||
| 71 | ); | ||
| 72 | WP_Smush.directory.updateProgressBar( progress ); | ||
| 73 | }, | ||
| 74 | |||
| 75 | onFinish() { | ||
| 76 | WP_Smush.directory.updateProgressBar( 100 ); | ||
| 77 | window.location.href = | ||
| 78 | window.wp_smush_msgs.directory_url + '&scan=done'; | ||
| 79 | }, | ||
| 80 | |||
| 81 | /** | ||
| 82 | * Displays an error when the scan request fails. | ||
| 83 | * | ||
| 84 | * @param {Object} res XHR object. | ||
| 85 | */ | ||
| 86 | showScanError( res ) { | ||
| 87 | const dialog = jQuery( '#wp-smush-progress-dialog' ); | ||
| 88 | |||
| 89 | // Add the error class to show/hide elements in the dialog. | ||
| 90 | dialog | ||
| 91 | .removeClass( 'wp-smush-exceed-limit' ) | ||
| 92 | .addClass( 'wp-smush-scan-error' ); | ||
| 93 | |||
| 94 | // Add the error status and description to the error message. | ||
| 95 | dialog | ||
| 96 | .find( '#smush-scan-error' ) | ||
| 97 | .text( `${ res.status } ${ res.statusText }` ); | ||
| 98 | |||
| 99 | // Show/hide the 403 error specific instructions. | ||
| 100 | const forbiddenMessage = dialog.find( '.smush-403-error-message' ); | ||
| 101 | if ( 403 !== res.status ) { | ||
| 102 | forbiddenMessage.addClass( 'sui-hidden' ); | ||
| 103 | } else { | ||
| 104 | forbiddenMessage.removeClass( 'sui-hidden' ); | ||
| 105 | } | ||
| 106 | }, | ||
| 107 | |||
| 108 | limitReached() { | ||
| 109 | const dialog = jQuery( '#wp-smush-progress-dialog' ); | ||
| 110 | |||
| 111 | dialog.addClass( 'wp-smush-exceed-limit' ); | ||
| 112 | dialog | ||
| 113 | .find( '#cancel-directory-smush' ) | ||
| 114 | .attr( 'data-tooltip', window.wp_smush_msgs.bulk_resume ); | ||
| 115 | dialog | ||
| 116 | .find( '.sui-box-body .sui-icon-close' ) | ||
| 117 | .removeClass( 'sui-icon-close' ) | ||
| 118 | .addClass( 'sui-icon-play' ); | ||
| 119 | dialog | ||
| 120 | .find( '#cancel-directory-smush' ) | ||
| 121 | .attr( 'id', 'cancel-directory-smush-disabled' ); | ||
| 122 | }, | ||
| 123 | |||
| 124 | resume() { | ||
| 125 | const dialog = jQuery( '#wp-smush-progress-dialog' ); | ||
| 126 | const resume = dialog.find( '#cancel-directory-smush-disabled' ); | ||
| 127 | |||
| 128 | dialog.removeClass( 'wp-smush-exceed-limit' ); | ||
| 129 | dialog | ||
| 130 | .find( '.sui-box-body .sui-icon-play' ) | ||
| 131 | .removeClass( 'sui-icon-play' ) | ||
| 132 | .addClass( 'sui-icon-close' ); | ||
| 133 | resume.attr( 'data-tooltip', 'Cancel' ); | ||
| 134 | resume.attr( 'id', 'cancel-directory-smush' ); | ||
| 135 | |||
| 136 | obj.scan(); | ||
| 137 | }, | ||
| 138 | }; | ||
| 139 | |||
| 140 | /** | ||
| 141 | * Execute a scan step recursively | ||
| 142 | * | ||
| 143 | * Private to avoid overriding | ||
| 144 | * | ||
| 145 | * @param {number} remainingSteps | ||
| 146 | */ | ||
| 147 | const step = function( remainingSteps ) { | ||
| 148 | if ( remainingSteps >= 0 ) { | ||
| 149 | currentStep = totalSteps - remainingSteps; | ||
| 150 | return jQuery.post( | ||
| 151 | ajaxurl, | ||
| 152 | { | ||
| 153 | action: 'directory_smush_check_step', | ||
| 154 | _ajax_nonce: window.wp_smush_msgs.nonce, | ||
| 155 | step: currentStep, | ||
| 156 | }, | ||
| 157 | ( response ) => { | ||
| 158 | // We're good - continue on. | ||
| 159 | if ( | ||
| 160 | 'undefined' !== typeof response.success && | ||
| 161 | response.success | ||
| 162 | ) { | ||
| 163 | if ( | ||
| 164 | 'undefined' !== typeof response.data && | ||
| 165 | 'undefined' !== typeof response.data.skipped && | ||
| 166 | true === response.data.skipped | ||
| 167 | ) { | ||
| 168 | skippedItems++; | ||
| 169 | } | ||
| 170 | |||
| 171 | currentStep++; | ||
| 172 | remainingSteps = remainingSteps - 1; | ||
| 173 | obj.onFinishStep( obj.getProgress() ); | ||
| 174 | step( remainingSteps ).fail( obj.showScanError ); | ||
| 175 | } else if ( | ||
| 176 | 'undefined' !== typeof response.data.error && | ||
| 177 | 'dir_smush_limit_exceeded' === response.data.error | ||
| 178 | ) { | ||
| 179 | // Limit reached. Stop. | ||
| 180 | obj.limitReached(); | ||
| 181 | } else { | ||
| 182 | // Error? never mind, continue, but count them. | ||
| 183 | failedItems++; | ||
| 184 | currentStep++; | ||
| 185 | remainingSteps = remainingSteps - 1; | ||
| 186 | obj.onFinishStep( obj.getProgress() ); | ||
| 187 | step( remainingSteps ).fail( obj.showScanError ); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | ); | ||
| 191 | } | ||
| 192 | return jQuery.post( | ||
| 193 | ajaxurl, | ||
| 194 | { | ||
| 195 | action: 'directory_smush_finish', | ||
| 196 | _ajax_nonce: window.wp_smush_msgs.nonce, | ||
| 197 | items: totalSteps - ( failedItems + skippedItems ), | ||
| 198 | failed: failedItems, | ||
| 199 | skipped: skippedItems, | ||
| 200 | }, | ||
| 201 | ( response ) => obj.onFinish( response ) | ||
| 202 | ); | ||
| 203 | }; | ||
| 204 | |||
| 205 | return obj; | ||
| 206 | }; | ||
| 207 | |||
| 208 | export default DirectoryScanner; |
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Lazy loading functionality. | ||
| 6 | * | ||
| 7 | * @since 3.0 | ||
| 8 | */ | ||
| 9 | ( function() { | ||
| 10 | 'use strict'; | ||
| 11 | |||
| 12 | WP_Smush.Lazyload = { | ||
| 13 | lazyloadEnableButton: document.getElementById( | ||
| 14 | 'smush-enable-lazyload' | ||
| 15 | ), | ||
| 16 | lazyloadDisableButton: document.getElementById( | ||
| 17 | 'smush-cancel-lazyload' | ||
| 18 | ), | ||
| 19 | |||
| 20 | init() { | ||
| 21 | const self = this; | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Handle "Activate" button click on disabled Lazy load page. | ||
| 25 | */ | ||
| 26 | if ( this.lazyloadEnableButton ) { | ||
| 27 | this.lazyloadEnableButton.addEventListener( 'click', ( e ) => { | ||
| 28 | e.preventDefault(); | ||
| 29 | e.currentTarget.classList.add( 'sui-button-onload' ); | ||
| 30 | |||
| 31 | this.toggle_lazy_load( true ); | ||
| 32 | } ); | ||
| 33 | } | ||
| 34 | |||
| 35 | /** | ||
| 36 | * Handle "Deactivate' button click on Lazy load page. | ||
| 37 | */ | ||
| 38 | if ( this.lazyloadDisableButton ) { | ||
| 39 | this.lazyloadDisableButton.addEventListener( 'click', ( e ) => { | ||
| 40 | e.preventDefault(); | ||
| 41 | e.currentTarget.classList.add( 'sui-button-onload' ); | ||
| 42 | |||
| 43 | this.toggle_lazy_load( false ); | ||
| 44 | } ); | ||
| 45 | } | ||
| 46 | |||
| 47 | /** | ||
| 48 | * Handle "Remove icon" button click on Lazy load page. | ||
| 49 | * | ||
| 50 | * This removes the image from the upload placeholder. | ||
| 51 | * | ||
| 52 | * @since 3.2.2 | ||
| 53 | */ | ||
| 54 | const removeSpinner = document.getElementById( | ||
| 55 | 'smush-remove-spinner' | ||
| 56 | ); | ||
| 57 | if ( removeSpinner ) { | ||
| 58 | removeSpinner.addEventListener( 'click', ( e ) => { | ||
| 59 | e.preventDefault(); | ||
| 60 | this.removeLoaderIcon(); | ||
| 61 | } ); | ||
| 62 | } | ||
| 63 | const removePlaceholder = document.getElementById( | ||
| 64 | 'smush-remove-placeholder' | ||
| 65 | ); | ||
| 66 | if ( removePlaceholder ) { | ||
| 67 | removePlaceholder.addEventListener( 'click', ( e ) => { | ||
| 68 | e.preventDefault(); | ||
| 69 | this.removeLoaderIcon( 'placeholder' ); | ||
| 70 | } ); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Handle "Remove" icon click. | ||
| 75 | * | ||
| 76 | * This removes the select icon from the list (not same as above functions). | ||
| 77 | * | ||
| 78 | * @since 3.2.2 | ||
| 79 | */ | ||
| 80 | const items = document.querySelectorAll( '.smush-ll-remove' ); | ||
| 81 | if ( items && 0 < items.length ) { | ||
| 82 | items.forEach( function( el ) { | ||
| 83 | el.addEventListener( 'click', ( e ) => { | ||
| 84 | e.preventDefault(); | ||
| 85 | e.target.closest( 'li' ).style.display = 'none'; | ||
| 86 | self.remove( | ||
| 87 | e.target.dataset.id, | ||
| 88 | e.target.dataset.type | ||
| 89 | ); | ||
| 90 | } ); | ||
| 91 | } ); | ||
| 92 | } | ||
| 93 | |||
| 94 | this.handlePredefinedPlaceholders(); | ||
| 95 | }, | ||
| 96 | |||
| 97 | /** | ||
| 98 | * Handle background color changes for the two predefined placeholders. | ||
| 99 | * | ||
| 100 | * @since 3.7.1 | ||
| 101 | */ | ||
| 102 | handlePredefinedPlaceholders() { | ||
| 103 | const pl1 = document.getElementById( 'placeholder-icon-1' ); | ||
| 104 | if ( pl1 ) { | ||
| 105 | pl1.addEventListener( 'click', () => this.changeColor( '#F3F3F3' ) ); | ||
| 106 | } | ||
| 107 | |||
| 108 | const pl2 = document.getElementById( 'placeholder-icon-2' ); | ||
| 109 | if ( pl2 ) { | ||
| 110 | pl2.addEventListener( 'click', () => this.changeColor( '#333333' ) ); | ||
| 111 | } | ||
| 112 | }, | ||
| 113 | |||
| 114 | /** | ||
| 115 | * Set color. | ||
| 116 | * | ||
| 117 | * @since 3.7.1 | ||
| 118 | * @param {string} color | ||
| 119 | */ | ||
| 120 | changeColor( color ) { | ||
| 121 | document.getElementById( 'smush-color-picker' ).value = color; | ||
| 122 | document.querySelector( '.sui-colorpicker-hex .sui-colorpicker-value > span > span' ).style.backgroundColor = color; | ||
| 123 | document.querySelector( '.sui-colorpicker-hex .sui-colorpicker-value > input' ).value = color; | ||
| 124 | }, | ||
| 125 | |||
| 126 | /** | ||
| 127 | * Toggle lazy loading. | ||
| 128 | * | ||
| 129 | * @since 3.2.0 | ||
| 130 | * | ||
| 131 | * @param {string} enable | ||
| 132 | */ | ||
| 133 | toggle_lazy_load( enable ) { | ||
| 134 | const nonceField = document.getElementsByName( | ||
| 135 | 'wp_smush_options_nonce' | ||
| 136 | ); | ||
| 137 | |||
| 138 | const xhr = new XMLHttpRequest(); | ||
| 139 | xhr.open( | ||
| 140 | 'POST', | ||
| 141 | ajaxurl + '?action=smush_toggle_lazy_load', | ||
| 142 | true | ||
| 143 | ); | ||
| 144 | xhr.setRequestHeader( | ||
| 145 | 'Content-type', | ||
| 146 | 'application/x-www-form-urlencoded' | ||
| 147 | ); | ||
| 148 | xhr.onload = () => { | ||
| 149 | if ( 200 === xhr.status ) { | ||
| 150 | const res = JSON.parse( xhr.response ); | ||
| 151 | if ( 'undefined' !== typeof res.success && res.success ) { | ||
| 152 | window.location.search = 'page=smush-lazy-load'; | ||
| 153 | } else if ( 'undefined' !== typeof res.data.message ) { | ||
| 154 | WP_Smush.helpers.showErrorNotice( res.data.message ); | ||
| 155 | document.querySelector( '.sui-button-onload' ).classList.remove( 'sui-button-onload' ); | ||
| 156 | } | ||
| 157 | } else { | ||
| 158 | WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status ); | ||
| 159 | document.querySelector( '.sui-button-onload' ).classList.remove( 'sui-button-onload' ); | ||
| 160 | } | ||
| 161 | }; | ||
| 162 | xhr.send( | ||
| 163 | 'param=' + enable + '&_ajax_nonce=' + nonceField[ 0 ].value | ||
| 164 | ); | ||
| 165 | }, | ||
| 166 | |||
| 167 | /** | ||
| 168 | * Add lazy load spinner icon. | ||
| 169 | * | ||
| 170 | * @since 3.2.2 | ||
| 171 | * @param {string} type Accepts: spinner, placeholder. | ||
| 172 | */ | ||
| 173 | addLoaderIcon( type = 'spinner' ) { | ||
| 174 | let frame; | ||
| 175 | |||
| 176 | // If the media frame already exists, reopen it. | ||
| 177 | if ( frame ) { | ||
| 178 | frame.open(); | ||
| 179 | return; | ||
| 180 | } | ||
| 181 | |||
| 182 | // Create a new media frame | ||
| 183 | frame = wp.media( { | ||
| 184 | title: 'Select or upload an icon', | ||
| 185 | button: { | ||
| 186 | text: 'Select icon', | ||
| 187 | }, | ||
| 188 | multiple: false, // Set to true to allow multiple files to be selected | ||
| 189 | } ); | ||
| 190 | |||
| 191 | // When an image is selected in the media frame... | ||
| 192 | frame.on( 'select', function() { | ||
| 193 | // Get media attachment details from the frame state | ||
| 194 | const attachment = frame | ||
| 195 | .state() | ||
| 196 | .get( 'selection' ) | ||
| 197 | .first() | ||
| 198 | .toJSON(); | ||
| 199 | |||
| 200 | // Send the attachment URL to our custom image input field. | ||
| 201 | const imageIcon = document.getElementById( | ||
| 202 | 'smush-' + type + '-icon-preview' | ||
| 203 | ); | ||
| 204 | imageIcon.style.backgroundImage = | ||
| 205 | 'url("' + attachment.url + '")'; | ||
| 206 | imageIcon.style.display = 'block'; | ||
| 207 | |||
| 208 | // Send the attachment id to our hidden input | ||
| 209 | document | ||
| 210 | .getElementById( 'smush-' + type + '-icon-file' ) | ||
| 211 | .setAttribute( 'value', attachment.id ); | ||
| 212 | |||
| 213 | // Hide the add image link | ||
| 214 | document.getElementById( | ||
| 215 | 'smush-upload-' + type | ||
| 216 | ).style.display = 'none'; | ||
| 217 | |||
| 218 | // Unhide the remove image link | ||
| 219 | const removeDiv = document.getElementById( | ||
| 220 | 'smush-remove-' + type | ||
| 221 | ); | ||
| 222 | removeDiv.querySelector( 'span' ).innerHTML = | ||
| 223 | attachment.filename; | ||
| 224 | removeDiv.style.display = 'block'; | ||
| 225 | } ); | ||
| 226 | |||
| 227 | // Finally, open the modal on click | ||
| 228 | frame.open(); | ||
| 229 | }, | ||
| 230 | |||
| 231 | /** | ||
| 232 | * Remove lazy load spinner icon. | ||
| 233 | * | ||
| 234 | * @since 3.2.2 | ||
| 235 | * @param {string} type Accepts: spinner, placeholder. | ||
| 236 | */ | ||
| 237 | removeLoaderIcon: ( type = 'spinner' ) => { | ||
| 238 | // Clear out the preview image | ||
| 239 | const imageIcon = document.getElementById( | ||
| 240 | 'smush-' + type + '-icon-preview' | ||
| 241 | ); | ||
| 242 | imageIcon.style.backgroundImage = ''; | ||
| 243 | imageIcon.style.display = 'none'; | ||
| 244 | |||
| 245 | // Un-hide the add image link | ||
| 246 | document.getElementById( 'smush-upload-' + type ).style.display = | ||
| 247 | 'block'; | ||
| 248 | |||
| 249 | // Hide the delete image link | ||
| 250 | document.getElementById( 'smush-remove-' + type ).style.display = | ||
| 251 | 'none'; | ||
| 252 | |||
| 253 | // Delete the image id from the hidden input | ||
| 254 | document | ||
| 255 | .getElementById( 'smush-' + type + '-icon-file' ) | ||
| 256 | .setAttribute( 'value', '' ); | ||
| 257 | }, | ||
| 258 | |||
| 259 | /** | ||
| 260 | * Remove item. | ||
| 261 | * | ||
| 262 | * @param {number} id Image ID. | ||
| 263 | * @param {string} type Accepts: spinner, placeholder. | ||
| 264 | */ | ||
| 265 | remove: ( id, type = 'spinner' ) => { | ||
| 266 | const nonceField = document.getElementsByName( | ||
| 267 | 'wp_smush_options_nonce' | ||
| 268 | ); | ||
| 269 | const xhr = new XMLHttpRequest(); | ||
| 270 | xhr.open( 'POST', ajaxurl + '?action=smush_remove_icon', true ); | ||
| 271 | xhr.setRequestHeader( | ||
| 272 | 'Content-type', | ||
| 273 | 'application/x-www-form-urlencoded' | ||
| 274 | ); | ||
| 275 | xhr.send( | ||
| 276 | 'id=' + | ||
| 277 | id + | ||
| 278 | '&type=' + | ||
| 279 | type + | ||
| 280 | '&_ajax_nonce=' + | ||
| 281 | nonceField[ 0 ].value | ||
| 282 | ); | ||
| 283 | }, | ||
| 284 | }; | ||
| 285 | |||
| 286 | WP_Smush.Lazyload.init(); | ||
| 287 | } )(); |
| 1 | /* global smush_vars */ | ||
| 2 | /* global _ */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * Adds a Smush Now button and displays stats in Media Attachment Details Screen | ||
| 6 | */ | ||
| 7 | (function ($, _) { | ||
| 8 | 'use strict'; | ||
| 9 | |||
| 10 | // Local reference to the WordPress media namespace. | ||
| 11 | const smushMedia = wp.media, | ||
| 12 | sharedTemplate = | ||
| 13 | "<span class='setting smush-stats' data-setting='smush'>" + | ||
| 14 | "<span class='name'><%= label %></span>" + | ||
| 15 | "<span class='value'><%= value %></span>" + | ||
| 16 | '</span>', | ||
| 17 | template = _.template(sharedTemplate); | ||
| 18 | |||
| 19 | /** | ||
| 20 | * Create the template. | ||
| 21 | * | ||
| 22 | * @param {string} smushHTML | ||
| 23 | * @return {Object} Template object | ||
| 24 | */ | ||
| 25 | const prepareTemplate = function (smushHTML) { | ||
| 26 | /** | ||
| 27 | * @param {Array} smush_vars.strings Localization strings. | ||
| 28 | * @param {Object} smush_vars Object from wp_localize_script() | ||
| 29 | */ | ||
| 30 | return template({ | ||
| 31 | label: smush_vars.strings.stats_label, | ||
| 32 | value: smushHTML, | ||
| 33 | }); | ||
| 34 | }; | ||
| 35 | |||
| 36 | if ( | ||
| 37 | 'undefined' !== typeof smushMedia.view && | ||
| 38 | 'undefined' !== typeof smushMedia.view.Attachment.Details.TwoColumn | ||
| 39 | ) { | ||
| 40 | // Local instance of the Attachment Details TwoColumn used in the edit attachment modal view | ||
| 41 | const smushMediaTwoColumn = | ||
| 42 | smushMedia.view.Attachment.Details.TwoColumn; | ||
| 43 | |||
| 44 | /** | ||
| 45 | * Add Smush details to attachment. | ||
| 46 | * | ||
| 47 | * A similar view to media.view.Attachment.Details | ||
| 48 | * for use in the Edit Attachment modal. | ||
| 49 | * | ||
| 50 | * @see wp-includes/js/media-grid.js | ||
| 51 | */ | ||
| 52 | smushMedia.view.Attachment.Details.TwoColumn = smushMediaTwoColumn.extend( | ||
| 53 | { | ||
| 54 | initialize() { | ||
| 55 | smushMediaTwoColumn.prototype.initialize.apply(this, arguments); | ||
| 56 | this.listenTo(this.model, 'change:smush', this.render); | ||
| 57 | }, | ||
| 58 | |||
| 59 | render() { | ||
| 60 | // Ensure that the main attachment fields are rendered. | ||
| 61 | smushMedia.view.Attachment.prototype.render.apply( | ||
| 62 | this, | ||
| 63 | arguments | ||
| 64 | ); | ||
| 65 | |||
| 66 | const smushHTML = this.model.get('smush'); | ||
| 67 | if (typeof smushHTML === 'undefined') { | ||
| 68 | return this; | ||
| 69 | } | ||
| 70 | |||
| 71 | this.model.fetch(); | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Detach the views, append our custom fields, make sure that our data is fully updated | ||
| 75 | * and re-render the updated view. | ||
| 76 | */ | ||
| 77 | this.views.detach(); | ||
| 78 | this.$el | ||
| 79 | .find('.settings') | ||
| 80 | .append(prepareTemplate(smushHTML)); | ||
| 81 | this.views.render(); | ||
| 82 | |||
| 83 | return this; | ||
| 84 | }, | ||
| 85 | } | ||
| 86 | ); | ||
| 87 | } | ||
| 88 | |||
| 89 | // Local instance of the Attachment Details TwoColumn used in the edit attachment modal view | ||
| 90 | const smushAttachmentDetails = smushMedia.view.Attachment.Details; | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Add Smush details to attachment. | ||
| 94 | */ | ||
| 95 | smushMedia.view.Attachment.Details = smushAttachmentDetails.extend({ | ||
| 96 | initialize() { | ||
| 97 | smushAttachmentDetails.prototype.initialize.apply(this, arguments); | ||
| 98 | this.listenTo(this.model, 'change:smush', this.render); | ||
| 99 | }, | ||
| 100 | |||
| 101 | render() { | ||
| 102 | // Ensure that the main attachment fields are rendered. | ||
| 103 | smushMedia.view.Attachment.prototype.render.apply(this, arguments); | ||
| 104 | |||
| 105 | const smushHTML = this.model.get('smush'); | ||
| 106 | if (typeof smushHTML === 'undefined') { | ||
| 107 | return this; | ||
| 108 | } | ||
| 109 | |||
| 110 | this.model.fetch(); | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Detach the views, append our custom fields, make sure that our data is fully updated | ||
| 114 | * and re-render the updated view. | ||
| 115 | */ | ||
| 116 | this.views.detach(); | ||
| 117 | this.$el.append(prepareTemplate(smushHTML)); | ||
| 118 | |||
| 119 | return this; | ||
| 120 | }, | ||
| 121 | }); | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Create a new MediaLibraryTaxonomyFilter we later will instantiate | ||
| 125 | * | ||
| 126 | * @since 3.0 | ||
| 127 | */ | ||
| 128 | const MediaLibraryTaxonomyFilter = wp.media.view.AttachmentFilters.extend({ | ||
| 129 | id: 'media-attachment-smush-filter', | ||
| 130 | |||
| 131 | createFilters() { | ||
| 132 | this.filters = { | ||
| 133 | all: { | ||
| 134 | text: smush_vars.strings.filter_all, | ||
| 135 | props: { stats: 'all' }, | ||
| 136 | priority: 10, | ||
| 137 | }, | ||
| 138 | |||
| 139 | unsmushed: { | ||
| 140 | text: smush_vars.strings.filter_not_processed, | ||
| 141 | props: { stats: 'unsmushed' }, | ||
| 142 | priority: 20, | ||
| 143 | }, | ||
| 144 | |||
| 145 | excluded: { | ||
| 146 | text: smush_vars.strings.filter_excl, | ||
| 147 | props: { stats: 'excluded' }, | ||
| 148 | priority: 30, | ||
| 149 | }, | ||
| 150 | |||
| 151 | failed: { | ||
| 152 | text: smush_vars.strings.filter_failed, | ||
| 153 | props: { stats: 'failed_processing' }, | ||
| 154 | priority: 40, | ||
| 155 | }, | ||
| 156 | }; | ||
| 157 | }, | ||
| 158 | }); | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Extend and override wp.media.view.AttachmentsBrowser to include our new filter. | ||
| 162 | * | ||
| 163 | * @since 3.0 | ||
| 164 | */ | ||
| 165 | const AttachmentsBrowser = wp.media.view.AttachmentsBrowser; | ||
| 166 | wp.media.view.AttachmentsBrowser = wp.media.view.AttachmentsBrowser.extend({ | ||
| 167 | createToolbar() { | ||
| 168 | // Make sure to load the original toolbar | ||
| 169 | AttachmentsBrowser.prototype.createToolbar.call(this); | ||
| 170 | this.toolbar.set( | ||
| 171 | 'MediaLibraryTaxonomyFilter', | ||
| 172 | new MediaLibraryTaxonomyFilter({ | ||
| 173 | controller: this.controller, | ||
| 174 | model: this.collection.props, | ||
| 175 | priority: -75, | ||
| 176 | }).render() | ||
| 177 | ); | ||
| 178 | }, | ||
| 179 | }); | ||
| 180 | })(jQuery, _); |
| 1 | /* global ajaxurl */ | ||
| 2 | /* global wp_smush_msgs */ | ||
| 3 | /* global WP_Smush */ | ||
| 4 | /* global SUI */ | ||
| 5 | |||
| 6 | ( function( $ ) { | ||
| 7 | 'use strict'; | ||
| 8 | |||
| 9 | /** | ||
| 10 | * Bulk compress page. | ||
| 11 | */ | ||
| 12 | $( 'form#smush-bulk-form' ).on( 'submit', function( e ) { | ||
| 13 | e.preventDefault(); | ||
| 14 | $( '#save-settings-button' ).addClass( 'sui-button-onload' ); | ||
| 15 | saveSettings( $( this ).serialize(), 'bulk' ); | ||
| 16 | runReCheck(); | ||
| 17 | } ); | ||
| 18 | |||
| 19 | /** | ||
| 20 | * Lazy load page. | ||
| 21 | */ | ||
| 22 | $( 'form#smush-lazy-load-form' ).on( 'submit', function( e ) { | ||
| 23 | e.preventDefault(); | ||
| 24 | $( '#save-settings-button' ).addClass( 'sui-button-onload-text' ); | ||
| 25 | saveSettings( $( this ).serialize(), 'lazy-load' ); | ||
| 26 | } ); | ||
| 27 | |||
| 28 | /** | ||
| 29 | * CDN page. | ||
| 30 | */ | ||
| 31 | $( 'form#smush-cdn-form' ).on( 'submit', function( e ) { | ||
| 32 | e.preventDefault(); | ||
| 33 | $( '#save-settings-button' ).addClass( 'sui-button-onload-text' ); | ||
| 34 | saveSettings( $( this ).serialize(), 'cdn' ); | ||
| 35 | } ); | ||
| 36 | |||
| 37 | /** | ||
| 38 | * Integrations page. | ||
| 39 | */ | ||
| 40 | $( 'form#smush-integrations-form' ).on( 'submit', function( e ) { | ||
| 41 | e.preventDefault(); | ||
| 42 | $( '#save-settings-button' ).addClass( 'sui-button-onload-text' ); | ||
| 43 | saveSettings( $( this ).serialize(), 'integrations' ); | ||
| 44 | } ); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Settings page. | ||
| 48 | */ | ||
| 49 | $( 'form#smush-settings-form' ).on( 'submit', function( e ) { | ||
| 50 | e.preventDefault(); | ||
| 51 | $( '#save-settings-button' ).addClass( 'sui-button-onload-text' ); | ||
| 52 | saveSettings( $( this ).serialize(), 'settings' ); | ||
| 53 | } ); | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Save settings. | ||
| 57 | * | ||
| 58 | * @param {string} settings JSON string of settings. | ||
| 59 | * @param {string} page Settings page. | ||
| 60 | */ | ||
| 61 | function saveSettings( settings, page ) { | ||
| 62 | const xhr = new XMLHttpRequest(); | ||
| 63 | |||
| 64 | xhr.open( 'POST', ajaxurl + '?action=smush_save_settings', true ); | ||
| 65 | xhr.setRequestHeader( | ||
| 66 | 'Content-type', | ||
| 67 | 'application/x-www-form-urlencoded' | ||
| 68 | ); | ||
| 69 | |||
| 70 | xhr.onload = () => { | ||
| 71 | $( '#save-settings-button' ).removeClass( | ||
| 72 | 'sui-button-onload-text sui-button-onload' | ||
| 73 | ); | ||
| 74 | |||
| 75 | if ( 200 === xhr.status ) { | ||
| 76 | const res = JSON.parse( xhr.response ); | ||
| 77 | if ( 'undefined' !== typeof res.success && res.success ) { | ||
| 78 | showSuccessNotice( wp_smush_msgs.settingsUpdated ); | ||
| 79 | } else if ( res.data && res.data.message ) { | ||
| 80 | WP_Smush.helpers.showErrorNotice( res.data.message ); | ||
| 81 | } else { | ||
| 82 | WP_Smush.helpers.showErrorNotice( 'Request failed.' ); | ||
| 83 | } | ||
| 84 | } else { | ||
| 85 | WP_Smush.helpers.showErrorNotice( 'Request failed. Returned status of ' + xhr.status ); | ||
| 86 | } | ||
| 87 | }; | ||
| 88 | |||
| 89 | xhr.send( 'page=' + page + '&' + settings + '&_ajax_nonce=' + wp_smush_msgs.nonce ); | ||
| 90 | } | ||
| 91 | |||
| 92 | /** | ||
| 93 | * Show successful update notice. | ||
| 94 | * | ||
| 95 | * @param {string} msg Notice message. | ||
| 96 | */ | ||
| 97 | function showSuccessNotice( msg ) { | ||
| 98 | const noticeMessage = `<p>${ msg }</p>`, | ||
| 99 | noticeOptions = { | ||
| 100 | type: 'success', | ||
| 101 | icon: 'check', | ||
| 102 | }; | ||
| 103 | |||
| 104 | SUI.openNotice( 'wp-smush-ajax-notice', noticeMessage, noticeOptions ); | ||
| 105 | |||
| 106 | const loadingButton = document.querySelector( '.sui-button-onload' ); | ||
| 107 | if ( loadingButton ) { | ||
| 108 | loadingButton.classList.remove( 'sui-button-onload' ); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | /** | ||
| 113 | * Re-check images from bulk smush and integrations pages. | ||
| 114 | */ | ||
| 115 | function runReCheck() { | ||
| 116 | $( '#save-settings-button' ).addClass( 'sui-button-onload' ); | ||
| 117 | |||
| 118 | const param = { | ||
| 119 | action: 'scan_for_resmush', | ||
| 120 | wp_smush_options_nonce: $( '#wp_smush_options_nonce' ).val(), | ||
| 121 | type: 'media', | ||
| 122 | }; | ||
| 123 | |||
| 124 | // Send ajax, Update Settings, And Check For resmush. | ||
| 125 | $.post( ajaxurl, $.param( param ) ).done( function() { | ||
| 126 | $( '#save-settings-button' ).removeClass( 'sui-button-onload' ); | ||
| 127 | } ); | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Parse remove data change. | ||
| 132 | */ | ||
| 133 | $( 'input[name=keep_data]' ).on( 'change', function( e ) { | ||
| 134 | const otherClass = | ||
| 135 | 'keep_data-true' === e.target.id | ||
| 136 | ? 'keep_data-false' | ||
| 137 | : 'keep_data-true'; | ||
| 138 | e.target.parentNode.classList.add( 'active' ); | ||
| 139 | document | ||
| 140 | .getElementById( otherClass ) | ||
| 141 | .parentNode.classList.remove( 'active' ); | ||
| 142 | } ); | ||
| 143 | |||
| 144 | /** | ||
| 145 | * Handle auto-detect checkbox toggle, to show/hide highlighting notice. | ||
| 146 | */ | ||
| 147 | $( 'input#detection' ).on( 'click', function() { | ||
| 148 | const noticeDiv = $( '.smush-highlighting-notice' ); | ||
| 149 | const warningDiv = $( '.smush-highlighting-warning' ); | ||
| 150 | |||
| 151 | // Setting enabled. | ||
| 152 | if ( $( this ).is( ':checked' ) ) { | ||
| 153 | // Highlighting is already active and setting not saved. | ||
| 154 | if ( noticeDiv.length > 0 ) { | ||
| 155 | noticeDiv.show(); | ||
| 156 | } else { | ||
| 157 | warningDiv.show(); | ||
| 158 | } | ||
| 159 | } else { | ||
| 160 | noticeDiv.hide(); | ||
| 161 | warningDiv.hide(); | ||
| 162 | } | ||
| 163 | } ); | ||
| 164 | }( jQuery ) ); |
This diff is collapsed.
Click to expand it.
| 1 | /* global WP_Smush */ | ||
| 2 | /* global ajaxurl */ | ||
| 3 | |||
| 4 | /** | ||
| 5 | * WebP functionality. | ||
| 6 | * | ||
| 7 | * @since 3.8.0 | ||
| 8 | */ | ||
| 9 | |||
| 10 | (function () { | ||
| 11 | 'use strict'; | ||
| 12 | |||
| 13 | WP_Smush.WebP = { | ||
| 14 | nonceField: document.getElementsByName('wp_smush_options_nonce'), | ||
| 15 | toggleModuleButton: document.getElementById('smush-toggle-webp-button'), | ||
| 16 | recheckStatusButton: document.getElementById('smush-webp-recheck'), | ||
| 17 | recheckStatusLink: document.getElementById('smush-webp-recheck-link'), | ||
| 18 | showWizardButton: document.getElementById('smush-webp-toggle-wizard'), | ||
| 19 | |||
| 20 | init() { | ||
| 21 | this.maybeShowDeleteAllSuccessNotice(); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Handles the "Deactivate" and "Get Started" buttons on the WebP page. | ||
| 25 | */ | ||
| 26 | if (this.toggleModuleButton) { | ||
| 27 | this.toggleModuleButton.addEventListener('click', (e) => | ||
| 28 | this.toggleWebp(e) | ||
| 29 | ); | ||
| 30 | } | ||
| 31 | |||
| 32 | /** | ||
| 33 | * Handle "RE-CHECK STATUS' button click on WebP page. | ||
| 34 | */ | ||
| 35 | if (this.recheckStatusButton) { | ||
| 36 | this.recheckStatusButton.addEventListener('click', (e) => { | ||
| 37 | e.preventDefault(); | ||
| 38 | this.recheckStatus(); | ||
| 39 | }); | ||
| 40 | } | ||
| 41 | |||
| 42 | /** | ||
| 43 | * Handle "RE-CHECK STATUS' link click on WebP page. | ||
| 44 | */ | ||
| 45 | if (this.recheckStatusLink) { | ||
| 46 | this.recheckStatusLink.addEventListener('click', (e) => { | ||
| 47 | e.preventDefault(); | ||
| 48 | this.recheckStatus(); | ||
| 49 | }); | ||
| 50 | } | ||
| 51 | |||
| 52 | /** | ||
| 53 | * Handles the "Delete WebP images" button. | ||
| 54 | */ | ||
| 55 | if (document.getElementById('wp-smush-webp-delete-all')) { | ||
| 56 | document | ||
| 57 | .getElementById('wp-smush-webp-delete-all') | ||
| 58 | .addEventListener('click', (e) => this.deleteAll(e)); | ||
| 59 | } | ||
| 60 | |||
| 61 | if (this.showWizardButton) { | ||
| 62 | this.showWizardButton.addEventListener( | ||
| 63 | 'click', | ||
| 64 | this.toggleWizard | ||
| 65 | ); | ||
| 66 | } | ||
| 67 | }, | ||
| 68 | |||
| 69 | /** | ||
| 70 | * Toggle WebP module. | ||
| 71 | * | ||
| 72 | * @param {Event} e | ||
| 73 | */ | ||
| 74 | toggleWebp(e) { | ||
| 75 | e.preventDefault(); | ||
| 76 | |||
| 77 | const button = e.currentTarget, | ||
| 78 | doEnable = 'enable' === button.dataset.action; | ||
| 79 | |||
| 80 | button.classList.add('sui-button-onload'); | ||
| 81 | |||
| 82 | const xhr = new XMLHttpRequest(); | ||
| 83 | xhr.open('POST', ajaxurl + '?action=smush_webp_toggle', true); | ||
| 84 | xhr.setRequestHeader( | ||
| 85 | 'Content-type', | ||
| 86 | 'application/x-www-form-urlencoded' | ||
| 87 | ); | ||
| 88 | |||
| 89 | xhr.onload = () => { | ||
| 90 | const res = JSON.parse(xhr.response); | ||
| 91 | |||
| 92 | if (200 === xhr.status) { | ||
| 93 | if ('undefined' !== typeof res.success && res.success) { | ||
| 94 | const scanPromise = this.runScan(); | ||
| 95 | scanPromise.onload = () => { | ||
| 96 | window.location.href = | ||
| 97 | window.wp_smush_msgs.localWebpURL; | ||
| 98 | }; | ||
| 99 | } else if ('undefined' !== typeof res.data.message) { | ||
| 100 | this.showNotice(res.data.message); | ||
| 101 | button.classList.remove('sui-button-onload'); | ||
| 102 | } | ||
| 103 | } else { | ||
| 104 | let message = window.wp_smush_msgs.generic_ajax_error; | ||
| 105 | if (res && 'undefined' !== typeof res.data.message) { | ||
| 106 | message = res.data.message; | ||
| 107 | } | ||
| 108 | this.showNotice(message); | ||
| 109 | button.classList.remove('sui-button-onload'); | ||
| 110 | } | ||
| 111 | }; | ||
| 112 | |||
| 113 | xhr.send( | ||
| 114 | 'param=' + doEnable + '&_ajax_nonce=' + this.nonceField[0].value | ||
| 115 | ); | ||
| 116 | }, | ||
| 117 | |||
| 118 | /** | ||
| 119 | * re-check server configuration for WebP. | ||
| 120 | */ | ||
| 121 | recheckStatus() { | ||
| 122 | this.recheckStatusButton.classList.add('sui-button-onload'); | ||
| 123 | |||
| 124 | const xhr = new XMLHttpRequest(); | ||
| 125 | xhr.open('POST', ajaxurl + '?action=smush_webp_get_status', true); | ||
| 126 | xhr.setRequestHeader( | ||
| 127 | 'Content-type', | ||
| 128 | 'application/x-www-form-urlencoded' | ||
| 129 | ); | ||
| 130 | xhr.onload = () => { | ||
| 131 | this.recheckStatusButton.classList.remove('sui-button-onload'); | ||
| 132 | let message = false; | ||
| 133 | const res = JSON.parse(xhr.response); | ||
| 134 | if (200 === xhr.status) { | ||
| 135 | const isConfigured = res.success ? '1' : '0'; | ||
| 136 | if ( | ||
| 137 | isConfigured !== | ||
| 138 | this.recheckStatusButton.dataset.isConfigured | ||
| 139 | ) { | ||
| 140 | // Reload the page when the configuration status changed. | ||
| 141 | location.reload(); | ||
| 142 | } | ||
| 143 | } else { | ||
| 144 | message = window.wp_smush_msgs.generic_ajax_error; | ||
| 145 | } | ||
| 146 | |||
| 147 | if (res && res.data) { | ||
| 148 | message = res.data; | ||
| 149 | } | ||
| 150 | |||
| 151 | if (message) { | ||
| 152 | this.showNotice(message); | ||
| 153 | } | ||
| 154 | }; | ||
| 155 | xhr.send('_ajax_nonce=' + window.wp_smush_msgs.webp_nonce); | ||
| 156 | }, | ||
| 157 | |||
| 158 | deleteAll(e) { | ||
| 159 | const button = e.currentTarget; | ||
| 160 | button.classList.add('sui-button-onload'); | ||
| 161 | |||
| 162 | let message = false; | ||
| 163 | const xhr = new XMLHttpRequest(); | ||
| 164 | xhr.open('POST', ajaxurl + '?action=smush_webp_delete_all', true); | ||
| 165 | xhr.setRequestHeader( | ||
| 166 | 'Content-type', | ||
| 167 | 'application/x-www-form-urlencoded' | ||
| 168 | ); | ||
| 169 | |||
| 170 | xhr.onload = () => { | ||
| 171 | const res = JSON.parse(xhr.response); | ||
| 172 | if (200 === xhr.status) { | ||
| 173 | if ('undefined' !== typeof res.success && res.success) { | ||
| 174 | const scanPromise = this.runScan(); | ||
| 175 | scanPromise.onload = () => { | ||
| 176 | location.search = | ||
| 177 | location.search + '¬ice=webp-deleted'; | ||
| 178 | }; | ||
| 179 | } else { | ||
| 180 | message = window.wp_smush_msgs.generic_ajax_error; | ||
| 181 | } | ||
| 182 | } else { | ||
| 183 | message = window.wp_smush_msgs.generic_ajax_error; | ||
| 184 | } | ||
| 185 | |||
| 186 | if (res && res.data && res.data.message) { | ||
| 187 | message = res.data.message; | ||
| 188 | } | ||
| 189 | |||
| 190 | if (message) { | ||
| 191 | button.classList.remove('sui-button-onload'); | ||
| 192 | |||
| 193 | const noticeMessage = `<p style="text-align: left;">${message}</p>`; | ||
| 194 | const noticeOptions = { | ||
| 195 | type: 'error', | ||
| 196 | icon: 'info', | ||
| 197 | autoclose: { | ||
| 198 | show: false, | ||
| 199 | }, | ||
| 200 | }; | ||
| 201 | |||
| 202 | window.SUI.openNotice( | ||
| 203 | 'wp-smush-webp-delete-all-error-notice', | ||
| 204 | noticeMessage, | ||
| 205 | noticeOptions | ||
| 206 | ); | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | |||
| 210 | xhr.send('_ajax_nonce=' + this.nonceField[0].value); | ||
| 211 | }, | ||
| 212 | |||
| 213 | toggleWizard(e) { | ||
| 214 | e.currentTarget.classList.add('sui-button-onload'); | ||
| 215 | |||
| 216 | const xhr = new XMLHttpRequest(); | ||
| 217 | xhr.open( | ||
| 218 | 'GET', | ||
| 219 | ajaxurl + | ||
| 220 | '?action=smush_toggle_webp_wizard&_ajax_nonce=' + | ||
| 221 | window.wp_smush_msgs.webp_nonce, | ||
| 222 | true | ||
| 223 | ); | ||
| 224 | xhr.onload = () => location.reload(); | ||
| 225 | xhr.send(); | ||
| 226 | }, | ||
| 227 | |||
| 228 | /** | ||
| 229 | * Triggers the scanning of images for updating the images to re-smush. | ||
| 230 | * | ||
| 231 | * @since 3.8.0 | ||
| 232 | */ | ||
| 233 | runScan() { | ||
| 234 | const xhr = new XMLHttpRequest(), | ||
| 235 | nonceField = document.getElementsByName( | ||
| 236 | 'wp_smush_options_nonce' | ||
| 237 | ); | ||
| 238 | |||
| 239 | xhr.open('POST', ajaxurl + '?action=scan_for_resmush', true); | ||
| 240 | xhr.setRequestHeader( | ||
| 241 | 'Content-type', | ||
| 242 | 'application/x-www-form-urlencoded' | ||
| 243 | ); | ||
| 244 | |||
| 245 | xhr.send('_ajax_nonce=' + nonceField[0].value); | ||
| 246 | |||
| 247 | return xhr; | ||
| 248 | }, | ||
| 249 | |||
| 250 | /** | ||
| 251 | * Show message (notice). | ||
| 252 | * | ||
| 253 | * @param {string} message | ||
| 254 | * @param {string} type | ||
| 255 | */ | ||
| 256 | showNotice(message, type) { | ||
| 257 | if ('undefined' === typeof message) { | ||
| 258 | return; | ||
| 259 | } | ||
| 260 | |||
| 261 | const noticeMessage = `<p>${message}</p>`; | ||
| 262 | const noticeOptions = { | ||
| 263 | type: type || 'error', | ||
| 264 | icon: 'info', | ||
| 265 | dismiss: { | ||
| 266 | show: true, | ||
| 267 | label: window.wp_smush_msgs.noticeDismiss, | ||
| 268 | tooltip: window.wp_smush_msgs.noticeDismissTooltip, | ||
| 269 | }, | ||
| 270 | autoclose: { | ||
| 271 | show: false, | ||
| 272 | }, | ||
| 273 | }; | ||
| 274 | |||
| 275 | window.SUI.openNotice( | ||
| 276 | 'wp-smush-ajax-notice', | ||
| 277 | noticeMessage, | ||
| 278 | noticeOptions | ||
| 279 | ); | ||
| 280 | }, | ||
| 281 | |||
| 282 | /** | ||
| 283 | * Show delete all webp success notice. | ||
| 284 | */ | ||
| 285 | maybeShowDeleteAllSuccessNotice() { | ||
| 286 | if (!document.getElementById('wp-smush-webp-delete-all-notice')) { | ||
| 287 | return; | ||
| 288 | } | ||
| 289 | const noticeMessage = `<p>${ | ||
| 290 | document.getElementById('wp-smush-webp-delete-all-notice') | ||
| 291 | .dataset.message | ||
| 292 | }</p>`; | ||
| 293 | |||
| 294 | const noticeOptions = { | ||
| 295 | type: 'success', | ||
| 296 | icon: 'check-tick', | ||
| 297 | dismiss: { | ||
| 298 | show: true, | ||
| 299 | }, | ||
| 300 | }; | ||
| 301 | |||
| 302 | window.SUI.openNotice( | ||
| 303 | 'wp-smush-webp-delete-all-notice', | ||
| 304 | noticeMessage, | ||
| 305 | noticeOptions | ||
| 306 | ); | ||
| 307 | }, | ||
| 308 | }; | ||
| 309 | |||
| 310 | WP_Smush.WebP.init(); | ||
| 311 | })(); |
| 1 | /* global ajaxurl */ | ||
| 2 | |||
| 3 | /** | ||
| 4 | * External dependencies | ||
| 5 | */ | ||
| 6 | import React from 'react'; | ||
| 7 | import ReactDOM from 'react-dom'; | ||
| 8 | |||
| 9 | /** | ||
| 10 | * WordPress dependencies | ||
| 11 | */ | ||
| 12 | import domReady from '@wordpress/dom-ready'; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * SUI dependencies | ||
| 16 | */ | ||
| 17 | import { TutorialsList, TutorialsSlider } from '@wpmudev/shared-tutorials'; | ||
| 18 | |||
| 19 | import MixPanel from "./mixpanel" | ||
| 20 | |||
| 21 | function hideTutorials() { | ||
| 22 | const xhr = new XMLHttpRequest(); | ||
| 23 | |||
| 24 | xhr.open( 'POST', ajaxurl + '?action=smush_hide_tutorials', true ); | ||
| 25 | xhr.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded' ); | ||
| 26 | |||
| 27 | xhr.onload = () => { | ||
| 28 | if ( 200 === xhr.status ) { | ||
| 29 | const noticeMessage = `<p>${ window.wp_smush_msgs.tutorialsRemoved }</p>`, | ||
| 30 | noticeOptions = { | ||
| 31 | type: 'success', | ||
| 32 | icon: 'check', | ||
| 33 | }; | ||
| 34 | |||
| 35 | window.SUI.openNotice( | ||
| 36 | 'wp-smush-ajax-notice', | ||
| 37 | noticeMessage, | ||
| 38 | noticeOptions | ||
| 39 | ); | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | xhr.send( '_ajax_nonce=' + window.wp_smush_msgs.nonce ); | ||
| 44 | } | ||
| 45 | |||
| 46 | /** | ||
| 47 | * Render the "Tutorials List" component. | ||
| 48 | * | ||
| 49 | * @since 2.8.5 | ||
| 50 | */ | ||
| 51 | domReady( function() { | ||
| 52 | // Tutorials section on Dashboard page. | ||
| 53 | const tutorialsDiv = document.getElementById( 'smush-dash-tutorials' ); | ||
| 54 | if ( tutorialsDiv ) { | ||
| 55 | ReactDOM.render( | ||
| 56 | <TutorialsSlider | ||
| 57 | category="11228" | ||
| 58 | title={ window.smush_tutorials.tutorials } | ||
| 59 | viewAll={ window.smush_tutorials.tutorials_link } | ||
| 60 | onCloseClick={ hideTutorials } | ||
| 61 | />, | ||
| 62 | tutorialsDiv | ||
| 63 | ); | ||
| 64 | } | ||
| 65 | |||
| 66 | // Tutorials page. | ||
| 67 | const tutorialsPageBox = document.getElementById( 'smush-box-tutorials' ); | ||
| 68 | if ( tutorialsPageBox ) { | ||
| 69 | ReactDOM.render( | ||
| 70 | <TutorialsList | ||
| 71 | category="11228" | ||
| 72 | title={ window.smush_tutorials.tutorials } | ||
| 73 | translate={ window.smush_tutorials.tutorials_strings } | ||
| 74 | />, | ||
| 75 | tutorialsPageBox | ||
| 76 | ); | ||
| 77 | } | ||
| 78 | } ); | ||
| 79 | |||
| 80 | jQuery(function ($) { | ||
| 81 | $(document).on('click', '#smush-box-tutorials li > [role="link"], #smush-dash-tutorials li > [role="link"]', function () { | ||
| 82 | const $tutorial = $(this); | ||
| 83 | const isDashPage = !!$tutorial.closest('#smush-dash-tutorials').length; | ||
| 84 | const decodeHtml = (html) => { | ||
| 85 | const txt = document.createElement("textarea"); | ||
| 86 | txt.innerHTML = html; | ||
| 87 | return txt.value; | ||
| 88 | }; | ||
| 89 | const title = decodeHtml($tutorial.attr('title')); | ||
| 90 | |||
| 91 | (new MixPanel()).track('Tutorial Opened', { | ||
| 92 | 'Tutorial Name': title, | ||
| 93 | 'Triggered From': isDashPage ? 'Dashboard' : 'Tutorials Tab' | ||
| 94 | }); | ||
| 95 | }); | ||
| 96 | }); |
| 1 | /* global ajaxurl */ | ||
| 2 | |||
| 3 | /** | ||
| 4 | * External dependencies | ||
| 5 | */ | ||
| 6 | import assign from 'lodash/assign'; | ||
| 7 | |||
| 8 | /** | ||
| 9 | * Wrapper function for ajax calls to WordPress. | ||
| 10 | * | ||
| 11 | * @since 3.12.0 | ||
| 12 | */ | ||
| 13 | function SmushFetcher() { | ||
| 14 | /** | ||
| 15 | * Request ajax with a promise. | ||
| 16 | * Use FormData Object as data if you need to upload file | ||
| 17 | * | ||
| 18 | * @param {string} action | ||
| 19 | * @param {Object|FormData} data | ||
| 20 | * @param {string} method | ||
| 21 | * @return {Promise<any>} Request results. | ||
| 22 | */ | ||
| 23 | function request(action, data = {}, method = 'POST') { | ||
| 24 | const args = { | ||
| 25 | url: ajaxurl, | ||
| 26 | method, | ||
| 27 | cache: false | ||
| 28 | }; | ||
| 29 | |||
| 30 | if (data instanceof FormData) { | ||
| 31 | data.append('action', action); | ||
| 32 | data.append('_ajax_nonce', window.wp_smush_msgs.nonce); | ||
| 33 | args.contentType = false; | ||
| 34 | args.processData = false; | ||
| 35 | } else { | ||
| 36 | data._ajax_nonce = data._ajax_nonce || window.wp_smush_msgs.nonce; | ||
| 37 | data.action = action; | ||
| 38 | } | ||
| 39 | args.data = data; | ||
| 40 | return new Promise((resolve, reject) => { | ||
| 41 | jQuery.ajax(args).done(resolve).fail(reject); | ||
| 42 | }).then((response) => { | ||
| 43 | if (typeof response !== 'object') { | ||
| 44 | response = JSON.parse(response); | ||
| 45 | } | ||
| 46 | return response; | ||
| 47 | }).catch((error) => { | ||
| 48 | console.error('Error:', error); | ||
| 49 | }); | ||
| 50 | } | ||
| 51 | |||
| 52 | const methods = { | ||
| 53 | /** | ||
| 54 | * Manage ajax for background. | ||
| 55 | */ | ||
| 56 | background: { | ||
| 57 | /** | ||
| 58 | * Start background process. | ||
| 59 | */ | ||
| 60 | start: () => { | ||
| 61 | return request('bulk_smush_start'); | ||
| 62 | }, | ||
| 63 | |||
| 64 | /** | ||
| 65 | * Cancel background process. | ||
| 66 | */ | ||
| 67 | cancel: () => { | ||
| 68 | return request('bulk_smush_cancel'); | ||
| 69 | }, | ||
| 70 | |||
| 71 | /** | ||
| 72 | * Initial State - Get stats on the first time. | ||
| 73 | */ | ||
| 74 | initState: () => { | ||
| 75 | return request('bulk_smush_get_status'); | ||
| 76 | }, | ||
| 77 | |||
| 78 | /** | ||
| 79 | * Get stats. | ||
| 80 | */ | ||
| 81 | getStatus: () => { | ||
| 82 | return request('bulk_smush_get_status'); | ||
| 83 | }, | ||
| 84 | |||
| 85 | getStats: () => { | ||
| 86 | return request('bulk_smush_get_global_stats'); | ||
| 87 | } | ||
| 88 | }, | ||
| 89 | smush: { | ||
| 90 | /** | ||
| 91 | * Sync stats. | ||
| 92 | */ | ||
| 93 | syncStats: ( data ) => { | ||
| 94 | data = data || {}; | ||
| 95 | return request('get_stats', data); | ||
| 96 | }, | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Ignore All. | ||
| 100 | */ | ||
| 101 | ignoreAll: ( type ) => { | ||
| 102 | return request('wp_smush_ignore_all_failed_items', { | ||
| 103 | type: type, | ||
| 104 | }); | ||
| 105 | }, | ||
| 106 | }, | ||
| 107 | |||
| 108 | /** | ||
| 109 | * Manage ajax for other requests | ||
| 110 | */ | ||
| 111 | common: { | ||
| 112 | /** | ||
| 113 | * Dismiss Notice. | ||
| 114 | * | ||
| 115 | * @param {string} dismissId Notification id. | ||
| 116 | */ | ||
| 117 | dismissNotice: (dismissId) => { | ||
| 118 | return request('smush_dismiss_notice', { | ||
| 119 | key: dismissId | ||
| 120 | }); | ||
| 121 | }, | ||
| 122 | |||
| 123 | /** | ||
| 124 | * Hide the new features modal. | ||
| 125 | * | ||
| 126 | * @param {string} modalID Notification id. | ||
| 127 | */ | ||
| 128 | hideModal: (modalID) => request('hide_modal', { | ||
| 129 | modal_id: modalID, | ||
| 130 | }), | ||
| 131 | |||
| 132 | /** | ||
| 133 | * Custom request. | ||
| 134 | * | ||
| 135 | * @param {Object} data | ||
| 136 | */ | ||
| 137 | request: (data) => data.action && request(data.action, data), | ||
| 138 | }, | ||
| 139 | }; | ||
| 140 | |||
| 141 | assign(this, methods); | ||
| 142 | } | ||
| 143 | |||
| 144 | const SmushAjax = new SmushFetcher(); | ||
| 145 | export default SmushAjax; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * External dependencies | ||
| 3 | */ | ||
| 4 | import React from 'react'; | ||
| 5 | import ReactDOM from 'react-dom'; | ||
| 6 | |||
| 7 | /** | ||
| 8 | * WordPress dependencies | ||
| 9 | */ | ||
| 10 | import domReady from '@wordpress/dom-ready'; | ||
| 11 | const { __, sprintf } = wp.i18n; | ||
| 12 | |||
| 13 | /** | ||
| 14 | * SUI dependencies | ||
| 15 | */ | ||
| 16 | import { Presets } from '@wpmudev/shared-presets'; | ||
| 17 | |||
| 18 | export const Configs = ({ isWidget }) => { | ||
| 19 | // TODO: Handle the html interpolation and translation better. | ||
| 20 | const proDescription = ( | ||
| 21 | <> | ||
| 22 | {__( | ||
| 23 | 'You can easily apply configs to multiple sites at once via ', | ||
| 24 | 'wp-smushit' | ||
| 25 | )} | ||
| 26 | <a | ||
| 27 | href={window.smushReact.links.hubConfigs} | ||
| 28 | target="_blank" | ||
| 29 | rel="noreferrer" | ||
| 30 | > | ||
| 31 | {__('the Hub.')} | ||
| 32 | </a> | ||
| 33 | </> | ||
| 34 | ); | ||
| 35 | |||
| 36 | const closeIcon = __('Close this dialog window', 'wp-smushit'), | ||
| 37 | cancelButton = __('Cancel', 'wp-smushit'); | ||
| 38 | |||
| 39 | const lang = { | ||
| 40 | title: __('Preset Configs', 'wp-smushit'), | ||
| 41 | upload: __('Upload', 'wp-smushit'), | ||
| 42 | save: __('Save config', 'wp-smushit'), | ||
| 43 | loading: __('Updating the config list…', 'wp-smushit'), | ||
| 44 | emptyNotice: __( | ||
| 45 | '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!', | ||
| 46 | 'wp-smushit' | ||
| 47 | ), | ||
| 48 | baseDescription: __( | ||
| 49 | 'Use configs to save preset configurations of Smush’s settings, then upload and apply them to your other sites in just a few clicks!', | ||
| 50 | 'wp-smushit' | ||
| 51 | ), | ||
| 52 | proDescription, | ||
| 53 | syncWithHubText: __( | ||
| 54 | 'Created or updated configs via the Hub?', | ||
| 55 | 'wp-smushit' | ||
| 56 | ), | ||
| 57 | syncWithHubButton: __('Check again', 'wp-smushit'), | ||
| 58 | apply: __('Apply', 'wp-smushit'), | ||
| 59 | download: __('Download', 'wp-smushit'), | ||
| 60 | edit: __('Name and Description', 'wp-smushit'), | ||
| 61 | delete: __('Delete', 'wp-smushit'), | ||
| 62 | notificationDismiss: __('Dismiss notice', 'wp-smushit'), | ||
| 63 | freeButtonLabel: __('Try The Hub', 'wp-smushit'), | ||
| 64 | defaultRequestError: sprintf( | ||
| 65 | /* translators: %s request status */ | ||
| 66 | __( | ||
| 67 | 'Request failed. Status: %s. Please reload the page and try again.', | ||
| 68 | 'wp-smushit' | ||
| 69 | ), | ||
| 70 | '{status}' | ||
| 71 | ), | ||
| 72 | uploadActionSuccessMessage: sprintf( | ||
| 73 | /* translators: %s request status */ | ||
| 74 | __( | ||
| 75 | '%s config has been uploaded successfully – you can now apply it to this site.', | ||
| 76 | 'wp-smushit' | ||
| 77 | ), | ||
| 78 | '{configName}' | ||
| 79 | ), | ||
| 80 | uploadWrongPluginErrorMessage: sprintf( | ||
| 81 | /* translators: %s {pluginName} */ | ||
| 82 | __( | ||
| 83 | 'The uploaded file is not a %s Config. Please make sure the uploaded file is correct.', | ||
| 84 | 'wp-smushit' | ||
| 85 | ), | ||
| 86 | '{pluginName}' | ||
| 87 | ), | ||
| 88 | applyAction: { | ||
| 89 | closeIcon, | ||
| 90 | cancelButton, | ||
| 91 | title: __('Apply Config', 'wp-smushit'), | ||
| 92 | description: sprintf( | ||
| 93 | /* translators: %s config name */ | ||
| 94 | __( | ||
| 95 | '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.', | ||
| 96 | 'wp-smushit' | ||
| 97 | ), | ||
| 98 | '{configName}' | ||
| 99 | ), | ||
| 100 | actionButton: __('Apply', 'wp-smushit'), | ||
| 101 | successMessage: sprintf( | ||
| 102 | /* translators: %s. config name */ | ||
| 103 | __('%s config has been applied successfully.', 'wp-smushit'), | ||
| 104 | '{configName}' | ||
| 105 | ), | ||
| 106 | }, | ||
| 107 | deleteAction: { | ||
| 108 | closeIcon, | ||
| 109 | cancelButton, | ||
| 110 | title: __('Delete Configuration File', 'wp-smushit'), | ||
| 111 | description: sprintf( | ||
| 112 | /* translators: %s config name */ | ||
| 113 | __( | ||
| 114 | 'Are you sure you want to delete %s? You will no longer be able to apply it to this or other connected sites.', | ||
| 115 | 'wp-smushit' | ||
| 116 | ), | ||
| 117 | '{configName}' | ||
| 118 | ), | ||
| 119 | actionButton: __('Delete', 'wp-smushit'), | ||
| 120 | }, | ||
| 121 | editAction: { | ||
| 122 | closeIcon, | ||
| 123 | cancelButton, | ||
| 124 | nameInput: __('Config name', 'wp-smushit'), | ||
| 125 | descriptionInput: __('Description', 'wp-smushit'), | ||
| 126 | emptyNameError: __('The config name is required', 'wp-smushit'), | ||
| 127 | actionButton: __('Save', 'wp-smushit'), | ||
| 128 | editTitle: __('Rename Config', 'wp-smushit'), | ||
| 129 | editDescription: __( | ||
| 130 | 'Change your config name to something recognizable.', | ||
| 131 | 'wp-smushit' | ||
| 132 | ), | ||
| 133 | createTitle: __('Save Config', 'wp-smushit'), | ||
| 134 | createDescription: __( | ||
| 135 | 'Save your current settings configuration. You’ll be able to then download and apply it to your other sites.', | ||
| 136 | 'wp-smushit' | ||
| 137 | ), | ||
| 138 | successMessage: sprintf( | ||
| 139 | /* translators: %s. config name */ | ||
| 140 | __('%s config created successfully.', 'wp-smushit'), | ||
| 141 | '{configName}' | ||
| 142 | ), | ||
| 143 | }, | ||
| 144 | settingsLabels: { | ||
| 145 | bulk_smush: __('Bulk Smush', 'wp-smushit'), | ||
| 146 | integrations: __('Integrations', 'wp-smushit'), | ||
| 147 | lazy_load: __('Lazy Load', 'wp-smushit'), | ||
| 148 | cdn: __('CDN', 'wp-smushit'), | ||
| 149 | webp_mod: __('Local WebP', 'wp-smushit'), | ||
| 150 | settings: __('Settings', 'wp-smushit'), | ||
| 151 | networkwide: __('Subsite Controls', 'wp-smushit'), | ||
| 152 | }, | ||
| 153 | }; | ||
| 154 | |||
| 155 | return ( | ||
| 156 | <Presets | ||
| 157 | isWidget={isWidget} | ||
| 158 | isPro={window.smushReact.isPro} | ||
| 159 | isWhitelabel={window.smushReact.hideBranding} | ||
| 160 | sourceLang={lang} | ||
| 161 | sourceUrls={window.smushReact.links} | ||
| 162 | requestsData={window.smushReact.requestsData} | ||
| 163 | /> | ||
| 164 | ); | ||
| 165 | }; | ||
| 166 | |||
| 167 | domReady(function () { | ||
| 168 | const configsPageBox = document.getElementById('smush-box-configs'); | ||
| 169 | if (configsPageBox) { | ||
| 170 | ReactDOM.render(<Configs isWidget={false} />, configsPageBox); | ||
| 171 | } | ||
| 172 | const configsWidgetBox = document.getElementById('smush-widget-configs'); | ||
| 173 | if (configsWidgetBox) { | ||
| 174 | ReactDOM.render(<Configs isWidget={true} />, configsWidgetBox); | ||
| 175 | } | ||
| 176 | }); |
| 1 | /* global ajaxurl */ | ||
| 2 | |||
| 3 | /** | ||
| 4 | * External dependencies | ||
| 5 | */ | ||
| 6 | import React from 'react'; | ||
| 7 | import ReactDOM from 'react-dom'; | ||
| 8 | |||
| 9 | /** | ||
| 10 | * WordPress dependencies | ||
| 11 | */ | ||
| 12 | import domReady from '@wordpress/dom-ready'; | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Internal dependencies | ||
| 16 | */ | ||
| 17 | import StepsBar from '../views/webp/steps-bar'; | ||
| 18 | import StepContent from '../views/webp/step-content'; | ||
| 19 | import FreeContent from '../views/webp/free-content'; | ||
| 20 | import StepFooter from '../views/webp/step-footer'; | ||
| 21 | |||
| 22 | export const WebpPage = ({ smushData }) => { | ||
| 23 | const [currentStep, setCurrentStep] = React.useState( | ||
| 24 | parseInt(smushData.startStep) | ||
| 25 | ); | ||
| 26 | |||
| 27 | React.useEffect(() => { | ||
| 28 | if (2 === currentStep) { | ||
| 29 | window.SUI.suiCodeSnippet(); | ||
| 30 | } | ||
| 31 | }, [currentStep]); | ||
| 32 | |||
| 33 | const [serverType, setServerType] = React.useState( | ||
| 34 | smushData.detectedServer | ||
| 35 | ); | ||
| 36 | const [rulesMethod, setRulesMethod] = React.useState('automatic'); | ||
| 37 | const [rulesError, setRulesError] = React.useState(false); | ||
| 38 | |||
| 39 | const makeRequest = (action, verb = 'GET') => { | ||
| 40 | return new Promise((resolve, reject) => { | ||
| 41 | const xhr = new XMLHttpRequest(); | ||
| 42 | xhr.open( | ||
| 43 | verb, | ||
| 44 | `${ajaxurl}?action=${action}&_ajax_nonce=${smushData.nonce}`, | ||
| 45 | true | ||
| 46 | ); | ||
| 47 | |||
| 48 | xhr.setRequestHeader( | ||
| 49 | 'Content-type', | ||
| 50 | 'application/x-www-form-urlencoded' | ||
| 51 | ); | ||
| 52 | |||
| 53 | xhr.onload = () => { | ||
| 54 | if (xhr.status >= 200 && xhr.status < 300) { | ||
| 55 | resolve(JSON.parse(xhr.response)); | ||
| 56 | } else { | ||
| 57 | reject(xhr); | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | xhr.onerror = () => reject(xhr); | ||
| 61 | xhr.send(); | ||
| 62 | }); | ||
| 63 | }; | ||
| 64 | |||
| 65 | const stepContent = smushData.isPro ? ( | ||
| 66 | <StepContent | ||
| 67 | currentStep={currentStep} | ||
| 68 | serverType={serverType} | ||
| 69 | rulesMethod={rulesMethod} | ||
| 70 | setRulesMethod={setRulesMethod} | ||
| 71 | rulesError={rulesError} | ||
| 72 | setServerType={setServerType} | ||
| 73 | smushData={smushData} | ||
| 74 | makeRequest={makeRequest} | ||
| 75 | /> | ||
| 76 | ) : ( | ||
| 77 | <FreeContent smushData={smushData} /> | ||
| 78 | ); | ||
| 79 | |||
| 80 | return ( | ||
| 81 | <React.Fragment> | ||
| 82 | <div className="sui-box-body sui-no-padding"> | ||
| 83 | <div className="sui-row-with-sidenav"> | ||
| 84 | <StepsBar smushData={smushData} currentStep={currentStep} /> | ||
| 85 | {stepContent} | ||
| 86 | </div> | ||
| 87 | </div> | ||
| 88 | {smushData.isPro && ( | ||
| 89 | <StepFooter | ||
| 90 | currentStep={currentStep} | ||
| 91 | setCurrentStep={setCurrentStep} | ||
| 92 | serverType={serverType} | ||
| 93 | rulesMethod={rulesMethod} | ||
| 94 | setRulesError={setRulesError} | ||
| 95 | makeRequest={makeRequest} | ||
| 96 | /> | ||
| 97 | )} | ||
| 98 | </React.Fragment> | ||
| 99 | ); | ||
| 100 | }; | ||
| 101 | |||
| 102 | domReady(function () { | ||
| 103 | const webpPageBox = document.getElementById('smush-box-webp-wizard'); | ||
| 104 | if (webpPageBox) { | ||
| 105 | ReactDOM.render( | ||
| 106 | <WebpPage smushData={window.smushReact} />, | ||
| 107 | webpPageBox | ||
| 108 | ); | ||
| 109 | } | ||
| 110 | }); |
| 1 | /** | ||
| 2 | * External dependencies | ||
| 3 | */ | ||
| 4 | import React from 'react'; | ||
| 5 | |||
| 6 | /** | ||
| 7 | * WordPress dependencies | ||
| 8 | */ | ||
| 9 | const { __ } = wp.i18n; | ||
| 10 | |||
| 11 | export default ({ smushData }) => { | ||
| 12 | return ( | ||
| 13 | <div className="sui-box-body"> | ||
| 14 | <div className="sui-message"> | ||
| 15 | <img | ||
| 16 | className="sui-image" | ||
| 17 | src={smushData.urls.freeImg} | ||
| 18 | alt={__('Smush WebP', 'wp-smushit')} | ||
| 19 | /> | ||
| 20 | |||
| 21 | <div className="sui-message-content"> | ||
| 22 | <p> | ||
| 23 | {__( | ||
| 24 | '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.', | ||
| 25 | 'wp-smushit' | ||
| 26 | )} | ||
| 27 | </p> | ||
| 28 | |||
| 29 | <ol className="sui-upsell-list"> | ||
| 30 | <li> | ||
| 31 | <span | ||
| 32 | className="sui-icon-check sui-sm" | ||
| 33 | aria-hidden="true" | ||
| 34 | /> | ||
| 35 | {__( | ||
| 36 | 'Add or automatically apply the rules to enable Local WebP feature.', | ||
| 37 | 'wp-smushit' | ||
| 38 | )} | ||
| 39 | </li> | ||
| 40 | <li> | ||
| 41 | <span | ||
| 42 | className="sui-icon-check sui-sm" | ||
| 43 | aria-hidden="true" | ||
| 44 | /> | ||
| 45 | {__( | ||
| 46 | 'Fix “Serve images in next-gen format" Google PageSpeed recommendation.', | ||
| 47 | 'wp-smushit' | ||
| 48 | )} | ||
| 49 | </li> | ||
| 50 | <li> | ||
| 51 | <span | ||
| 52 | className="sui-icon-check sui-sm" | ||
| 53 | aria-hidden="true" | ||
| 54 | /> | ||
| 55 | {__( | ||
| 56 | 'Serve WebP version of images in the browsers that support it and fall back to JPEGs and PNGs for non supported browsers.', | ||
| 57 | 'wp-smushit' | ||
| 58 | )} | ||
| 59 | </li> | ||
| 60 | </ol> | ||
| 61 | |||
| 62 | <p className="sui-margin-top"> | ||
| 63 | <a | ||
| 64 | href={smushData.urls.upsell} | ||
| 65 | className="sui-button sui-button-purple" | ||
| 66 | style={{ marginRight: '30px' }} | ||
| 67 | target="_blank" | ||
| 68 | rel="noreferrer" | ||
| 69 | > | ||
| 70 | {__('Try WebP for free', 'wp-smushit')} | ||
| 71 | </a> | ||
| 72 | <a | ||
| 73 | href={smushData.urls.webpDoc} | ||
| 74 | style={{ color: '#8D00B1' }} | ||
| 75 | target="_blank" | ||
| 76 | rel="noreferrer" | ||
| 77 | > | ||
| 78 | {__('Learn more', 'wp-smushit')} | ||
| 79 | </a> | ||
| 80 | </p> | ||
| 81 | </div> | ||
| 82 | </div> | ||
| 83 | </div> | ||
| 84 | ); | ||
| 85 | }; |
This diff is collapsed.
Click to expand it.
| 1 | /** | ||
| 2 | * External dependencies | ||
| 3 | */ | ||
| 4 | import React from 'react'; | ||
| 5 | |||
| 6 | /** | ||
| 7 | * WordPress dependencies | ||
| 8 | */ | ||
| 9 | const { __ } = wp.i18n; | ||
| 10 | |||
| 11 | export default ({ | ||
| 12 | currentStep, | ||
| 13 | setCurrentStep, | ||
| 14 | serverType, | ||
| 15 | rulesMethod, | ||
| 16 | setRulesError, | ||
| 17 | makeRequest, | ||
| 18 | }) => { | ||
| 19 | const genericRequestError = __( | ||
| 20 | 'Something went wrong with the request.', | ||
| 21 | 'wp-smushit' | ||
| 22 | ); | ||
| 23 | |||
| 24 | const checkStatus = () => { | ||
| 25 | setRulesError(false); | ||
| 26 | |||
| 27 | makeRequest('smush_webp_get_status') | ||
| 28 | .then((res) => { | ||
| 29 | if (res.success) { | ||
| 30 | setCurrentStep(currentStep + 1); | ||
| 31 | } else { | ||
| 32 | setRulesError(res.data); | ||
| 33 | } | ||
| 34 | }) | ||
| 35 | .catch(() => setRulesError(genericRequestError)); | ||
| 36 | }; | ||
| 37 | |||
| 38 | const applyRules = () => { | ||
| 39 | setRulesError(false); | ||
| 40 | |||
| 41 | makeRequest('smush_webp_apply_htaccess_rules') | ||
| 42 | .then((res) => { | ||
| 43 | if (res.success) { | ||
| 44 | return checkStatus(); | ||
| 45 | } | ||
| 46 | |||
| 47 | setRulesError(res.data); | ||
| 48 | }) | ||
| 49 | .catch(() => setRulesError(genericRequestError)); | ||
| 50 | }; | ||
| 51 | |||
| 52 | const hideWizard = (e) => { | ||
| 53 | e.currentTarget.classList.add( | ||
| 54 | 'sui-button-onload', | ||
| 55 | 'sui-button-onload-text' | ||
| 56 | ); | ||
| 57 | makeRequest('smush_toggle_webp_wizard').then(() => location.reload()); | ||
| 58 | }; | ||
| 59 | |||
| 60 | // Markup stuff. | ||
| 61 | let buttonsLeft; | ||
| 62 | |||
| 63 | const quitButton = ( | ||
| 64 | <button | ||
| 65 | type="button" | ||
| 66 | className="sui-button sui-button-ghost" | ||
| 67 | onClick={hideWizard} | ||
| 68 | > | ||
| 69 | <span className="sui-loading-text"> | ||
| 70 | <span className="sui-icon-logout" aria-hidden="true"></span> | ||
| 71 | <span className="sui-hidden-xs"> | ||
| 72 | {__('Quit setup', 'wp-smushit')} | ||
| 73 | </span> | ||
| 74 | <span className="sui-hidden-sm sui-hidden-md sui-hidden-lg"> | ||
| 75 | {__('Quit', 'wp-smushit')} | ||
| 76 | </span> | ||
| 77 | </span> | ||
| 78 | |||
| 79 | <span | ||
| 80 | className="sui-icon-loader sui-loading" | ||
| 81 | aria-hidden="true" | ||
| 82 | ></span> | ||
| 83 | </button> | ||
| 84 | ); | ||
| 85 | |||
| 86 | if (1 !== currentStep) { | ||
| 87 | buttonsLeft = ( | ||
| 88 | <button | ||
| 89 | type="button" | ||
| 90 | className="sui-button sui-button-compound sui-button-ghost" | ||
| 91 | onClick={() => setCurrentStep(currentStep - 1)} | ||
| 92 | > | ||
| 93 | <span className="sui-compound-desktop" aria-hidden="true"> | ||
| 94 | <span className="sui-icon-arrow-left"></span> | ||
| 95 | {__('Previous', 'wp-smushit')} | ||
| 96 | </span> | ||
| 97 | |||
| 98 | <span className="sui-compound-mobile" aria-hidden="true"> | ||
| 99 | <span className="sui-icon-arrow-left"></span> | ||
| 100 | </span> | ||
| 101 | |||
| 102 | <span className="sui-screen-reader-text"> | ||
| 103 | {__('Previous', 'wp-smushit')} | ||
| 104 | </span> | ||
| 105 | </button> | ||
| 106 | ); | ||
| 107 | } | ||
| 108 | |||
| 109 | const getButtonsRight = () => { | ||
| 110 | if (1 === currentStep) { | ||
| 111 | return ( | ||
| 112 | <button | ||
| 113 | type="button" | ||
| 114 | className="sui-button sui-button-blue sui-button-icon-right" | ||
| 115 | onClick={() => setCurrentStep(currentStep + 1)} | ||
| 116 | > | ||
| 117 | {__('Next', 'wp-smushit')} | ||
| 118 | <span | ||
| 119 | className="sui-icon-arrow-right" | ||
| 120 | aria-hidden="true" | ||
| 121 | ></span> | ||
| 122 | </button> | ||
| 123 | ); | ||
| 124 | } | ||
| 125 | |||
| 126 | if (2 === currentStep) { | ||
| 127 | if ('apache' === serverType && 'automatic' === rulesMethod) { | ||
| 128 | return ( | ||
| 129 | <button | ||
| 130 | type="button" | ||
| 131 | className="sui-button sui-button-blue" | ||
| 132 | onClick={applyRules} | ||
| 133 | > | ||
| 134 | {__('Apply rules', 'wp-smushit')} | ||
| 135 | </button> | ||
| 136 | ); | ||
| 137 | } | ||
| 138 | |||
| 139 | return ( | ||
| 140 | <button | ||
| 141 | type="button" | ||
| 142 | className="sui-button sui-button-blue" | ||
| 143 | onClick={checkStatus} | ||
| 144 | > | ||
| 145 | {__('Check status', 'wp-smushit')} | ||
| 146 | </button> | ||
| 147 | ); | ||
| 148 | } | ||
| 149 | |||
| 150 | return ( | ||
| 151 | <button | ||
| 152 | type="button" | ||
| 153 | className="sui-button sui-button-blue" | ||
| 154 | onClick={hideWizard} | ||
| 155 | > | ||
| 156 | <span className="sui-button-text-default"> | ||
| 157 | {__('Finish', 'wp-smushit')} | ||
| 158 | </span> | ||
| 159 | |||
| 160 | <span className="sui-button-text-onload"> | ||
| 161 | <span | ||
| 162 | className="sui-icon-loader sui-loading" | ||
| 163 | aria-hidden="true" | ||
| 164 | ></span> | ||
| 165 | {__('Finishing setup…', 'wp-smushit')} | ||
| 166 | </span> | ||
| 167 | </button> | ||
| 168 | ); | ||
| 169 | }; | ||
| 170 | |||
| 171 | return ( | ||
| 172 | <div className="sui-box-footer"> | ||
| 173 | <div className="sui-actions-left"> | ||
| 174 | {quitButton} | ||
| 175 | {buttonsLeft} | ||
| 176 | </div> | ||
| 177 | <div className="sui-actions-right">{getButtonsRight()}</div> | ||
| 178 | </div> | ||
| 179 | ); | ||
| 180 | }; |
| 1 | /** | ||
| 2 | * External dependencies | ||
| 3 | */ | ||
| 4 | import React from 'react'; | ||
| 5 | |||
| 6 | /** | ||
| 7 | * WordPress dependencies | ||
| 8 | */ | ||
| 9 | const { __ } = wp.i18n; | ||
| 10 | |||
| 11 | export default ({ currentStep, smushData }) => { | ||
| 12 | const getStepClass = (step) => { | ||
| 13 | const stepClass = 'smush-wizard-bar-step'; | ||
| 14 | |||
| 15 | if (!smushData.isPro) { | ||
| 16 | return stepClass + ' disabled'; | ||
| 17 | } | ||
| 18 | |||
| 19 | if (step > currentStep) { | ||
| 20 | return stepClass; | ||
| 21 | } | ||
| 22 | |||
| 23 | return ( | ||
| 24 | stepClass + | ||
| 25 | (step === currentStep ? ' current' : ' sui-tooltip done') | ||
| 26 | ); | ||
| 27 | }; | ||
| 28 | |||
| 29 | const getStepNumber = (step) => { | ||
| 30 | return currentStep > step ? ( | ||
| 31 | <span className="sui-icon-check" aria-hidden="true"></span> | ||
| 32 | ) : ( | ||
| 33 | step | ||
| 34 | ); | ||
| 35 | }; | ||
| 36 | |||
| 37 | const steps = [ | ||
| 38 | { number: 1, title: __('Server Type', 'wp-smushit') }, | ||
| 39 | { number: 2, title: __('Add Rules', 'wp-smushit') }, | ||
| 40 | { number: 3, title: __('Finish Setup', 'wp-smushit') }, | ||
| 41 | ]; | ||
| 42 | |||
| 43 | return ( | ||
| 44 | <div className="sui-sidenav"> | ||
| 45 | <span className="smush-wizard-bar-subtitle"> | ||
| 46 | {__('Setup', 'wp-smushit')} | ||
| 47 | </span> | ||
| 48 | <div className="smush-sidenav-title"> | ||
| 49 | <h4>{__('Local WebP', 'wp-smushit')}</h4> | ||
| 50 | {!smushData.isPro && ( | ||
| 51 | <span className="sui-tag sui-tag-pro"> | ||
| 52 | {__('Pro', 'wp-smushit')} | ||
| 53 | </span> | ||
| 54 | )} | ||
| 55 | </div> | ||
| 56 | |||
| 57 | <div className="smush-wizard-steps-container"> | ||
| 58 | <svg | ||
| 59 | className="smush-svg-mobile" | ||
| 60 | focusable="false" | ||
| 61 | aria-hidden="true" | ||
| 62 | > | ||
| 63 | <line | ||
| 64 | x1="0" | ||
| 65 | x2="50%" | ||
| 66 | stroke={1 !== currentStep ? '#1ABC9C' : '#E6E6E6'} | ||
| 67 | /> | ||
| 68 | <line | ||
| 69 | x1="50%" | ||
| 70 | x2="100%" | ||
| 71 | stroke={3 === currentStep ? '#1ABC9C' : '#E6E6E6'} | ||
| 72 | /> | ||
| 73 | </svg> | ||
| 74 | <ul> | ||
| 75 | {steps.map((step) => ( | ||
| 76 | <React.Fragment key={step.number}> | ||
| 77 | <li | ||
| 78 | className={getStepClass(step.number)} | ||
| 79 | data-tooltip={__( | ||
| 80 | 'This stage is already completed.', | ||
| 81 | 'wp-smushit' | ||
| 82 | )} | ||
| 83 | > | ||
| 84 | <div className="smush-wizard-bar-step-number"> | ||
| 85 | {getStepNumber(step.number)} | ||
| 86 | </div> | ||
| 87 | {step.title} | ||
| 88 | </li> | ||
| 89 | {3 !== step.number && ( | ||
| 90 | <svg | ||
| 91 | data={step.number} | ||
| 92 | data2={currentStep} | ||
| 93 | className="smush-svg-desktop" | ||
| 94 | focusable="false" | ||
| 95 | aria-hidden="true" | ||
| 96 | > | ||
| 97 | <line | ||
| 98 | y1="0" | ||
| 99 | y2="40px" | ||
| 100 | stroke={ | ||
| 101 | step.number < currentStep | ||
| 102 | ? '#1ABC9C' | ||
| 103 | : '#E6E6E6' | ||
| 104 | } | ||
| 105 | /> | ||
| 106 | </svg> | ||
| 107 | )} | ||
| 108 | </React.Fragment> | ||
| 109 | ))} | ||
| 110 | </ul> | ||
| 111 | </div> | ||
| 112 | </div> | ||
| 113 | ); | ||
| 114 | }; |
| 1 | @include body-class(true) { | ||
| 2 | &.sui-color-accessible { | ||
| 3 | .smush-final-log .smush-bulk-error-row { | ||
| 4 | box-shadow: inset 2px 0 0 0 $accessible-dark; | ||
| 5 | .smush-bulk-image-data:before { | ||
| 6 | color: $accessible-dark; | ||
| 7 | } | ||
| 8 | } | ||
| 9 | // Bulk Smush Fancy Tree | ||
| 10 | ul.fancytree-container { | ||
| 11 | .fancytree-selected { | ||
| 12 | background-color: #F8F8F8; | ||
| 13 | span.fancytree-checkbox { | ||
| 14 | border: 1px solid $accessible-dark; | ||
| 15 | background-color: $accessible-dark; | ||
| 16 | } | ||
| 17 | } | ||
| 18 | span.fancytree-expander:before, | ||
| 19 | span.fancytree-icon:before, | ||
| 20 | span.fancytree-title { | ||
| 21 | color: $accessible-dark; | ||
| 22 | } | ||
| 23 | } | ||
| 24 | // CDN | ||
| 25 | .smush-filename-extension { | ||
| 26 | background-color: $accessible-dark; | ||
| 27 | } | ||
| 28 | // Check images button. | ||
| 29 | .sui-button { | ||
| 30 | &.smush-button-check-success:before { | ||
| 31 | color: $accessible-light; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | // Smush submit note. | ||
| 35 | .smush-submit-note { | ||
| 36 | color: $accessible-dark; | ||
| 37 | } | ||
| 38 | |||
| 39 | // Hightlight lazyload spinner. | ||
| 40 | .sui-lazyload .sui-box-selector [name="animation[spinner-icon]"]:checked+span { | ||
| 41 | background-color: rgba(220,220,222, 0.7)!important; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { | ||
| 47 | .sui-wrap .sui-toggle-slider { | ||
| 48 | -ms-high-contrast-adjust: none; | ||
| 49 | } | ||
| 50 | } |
| 1 | // This needs to be here. | ||
| 2 | @import "modules/variables"; | ||
| 3 | |||
| 4 | // Share UI styles | ||
| 5 | @import "~@wpmudev/shared-ui/scss/functions"; | ||
| 6 | @import "~@wpmudev/shared-ui/scss/colors"; | ||
| 7 | @import "~@wpmudev/shared-ui/scss/variables"; | ||
| 8 | $google-fonts-url: 'https://fonts.bunny.net/css?family=Roboto:400,500,700'; | ||
| 9 | @import "~@wpmudev/shared-ui/scss/mixins"; | ||
| 10 | @import "~@wpmudev/shared-ui/scss/accessibility"; | ||
| 11 | @import "~@wpmudev/shared-ui/scss/animations"; | ||
| 12 | @import "~@wpmudev/shared-ui/scss/typography"; | ||
| 13 | @import "~@wpmudev/shared-ui/scss/icons"; | ||
| 14 | @import "~@wpmudev/shared-ui/scss/buttons"; | ||
| 15 | @import "~@wpmudev/shared-ui/scss/toggles"; | ||
| 16 | @import "~@wpmudev/shared-ui/scss/boxes"; | ||
| 17 | @import "~@wpmudev/shared-ui/scss/box-settings"; | ||
| 18 | @import "~@wpmudev/shared-ui/scss/layout"; | ||
| 19 | @import "~@wpmudev/shared-ui/scss/notifications"; | ||
| 20 | @import "~@wpmudev/shared-ui/scss/header"; | ||
| 21 | @import "~@wpmudev/shared-ui/scss/summary"; | ||
| 22 | @import "~@wpmudev/shared-ui/scss/list"; | ||
| 23 | @import "~@wpmudev/shared-ui/scss/tooltips"; | ||
| 24 | @import "~@wpmudev/shared-ui/scss/select2"; | ||
| 25 | @import "~@wpmudev/shared-ui/scss/tags"; | ||
| 26 | @import "~@wpmudev/shared-ui/scss/forms"; | ||
| 27 | @import "~@wpmudev/shared-ui/scss/radio-checkbox"; | ||
| 28 | @import "~@wpmudev/shared-ui/scss/tabs"; | ||
| 29 | @import "~@wpmudev/shared-ui/scss/sidenav"; | ||
| 30 | @import "~@wpmudev/shared-ui/scss/dropdowns"; | ||
| 31 | @import "~@wpmudev/shared-ui/scss/scores"; | ||
| 32 | @import "~@wpmudev/shared-ui/scss/footer"; | ||
| 33 | @import "~@wpmudev/shared-ui/scss/progress-bars"; | ||
| 34 | @import "~@wpmudev/shared-ui/scss/modals"; | ||
| 35 | @import "~@wpmudev/shared-ui/scss/utility"; | ||
| 36 | @import "~@wpmudev/shared-ui/scss/wp-admin-notices"; | ||
| 37 | @import "~@wpmudev/shared-ui/scss/tables"; | ||
| 38 | @import "~@wpmudev/shared-ui/scss/accordions"; | ||
| 39 | // Used on lazy loading page (since 3.2.2). | ||
| 40 | @import "~@wpmudev/shared-ui/scss/box-selectors"; | ||
| 41 | @import "~@wpmudev/shared-ui/scss/upload"; | ||
| 42 | @import "~@wpmudev/shared-ui/scss/_colorpickers.scss"; | ||
| 43 | // Upgrade page (since 3.2.3). | ||
| 44 | @import "~@wpmudev/shared-ui/scss/upgrade-page"; | ||
| 45 | @import "~@wpmudev/shared-ui/scss/reviews"; | ||
| 46 | // Used on WebP page (since 3.8.0). | ||
| 47 | @import "~@wpmudev/shared-ui/scss/_code-snippet.scss"; | ||
| 48 | // Upsells (since 3.9.1). | ||
| 49 | @import "~@wpmudev/shared-ui/scss/upsells"; | ||
| 50 | |||
| 51 | // App styles | ||
| 52 | @import "modules/admin"; | ||
| 53 | @import "modules/directory-smush"; | ||
| 54 | @import "modules/cdn"; | ||
| 55 | @import "modules/webp"; | ||
| 56 | |||
| 57 | // SUI Color Accessibility | ||
| 58 | @import "~@wpmudev/shared-ui/scss/color-accessibility"; | ||
| 59 | @import "accessibility/color-accessibility"; |
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
| 1 | @import "variables"; | ||
| 2 | |||
| 3 | /** | ||
| 4 | * CDN styles | ||
| 5 | * | ||
| 6 | * @since 3.0 | ||
| 7 | */ | ||
| 8 | |||
| 9 | @include body-class { | ||
| 10 | |||
| 11 | .sui-wrap { | ||
| 12 | |||
| 13 | .sui-box-settings-row .sui-box-settings-col-1 { | ||
| 14 | vertical-align: top; | ||
| 15 | } | ||
| 16 | |||
| 17 | &.wrap-smush-cdn { | ||
| 18 | .sui-block-content-center p { | ||
| 19 | max-width: 600px; | ||
| 20 | margin: 20px auto 30px; | ||
| 21 | } | ||
| 22 | .sui-box-header .sui-actions-right .sui-icon-info{ | ||
| 23 | font-size: 16px; | ||
| 24 | position: relative; | ||
| 25 | top: 1.5px; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | .sui-cdn { | ||
| 30 | form p:first-of-type { | ||
| 31 | margin-top: 0; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | .wp-smush-stats { | ||
| 35 | display: flex; | ||
| 36 | align-items: center; | ||
| 37 | line-height: 0; | ||
| 38 | |||
| 39 | .sui-tooltip { | ||
| 40 | line-height: 10px; | ||
| 41 | margin-right: 10px; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | /* Filename Extensions Icons */ | ||
| 46 | .smush-filename-extension { | ||
| 47 | border-radius: 4px; | ||
| 48 | display: inline-block; | ||
| 49 | font-size: 9px; | ||
| 50 | font-weight: 600; | ||
| 51 | color: #fff; | ||
| 52 | text-transform: uppercase; | ||
| 53 | text-align: center; | ||
| 54 | line-height: 43px; | ||
| 55 | height: 30px; | ||
| 56 | margin: 0 5px 0 0; | ||
| 57 | width: 30px; | ||
| 58 | |||
| 59 | &.smush-extension-jpeg, | ||
| 60 | &.smush-extension-jpg { background-color: #F7E100; } | ||
| 61 | &.smush-extension-png { background-color: #FFB694; } | ||
| 62 | &.smush-extension-gif { background-color: #72D5D4; } | ||
| 63 | &.smush-extension-webp { background-color: #72ADD5; } | ||
| 64 | &.smush-extension-svg { background-color: #88D572; } | ||
| 65 | &.smush-extension-iframe { | ||
| 66 | background-color: #8772D5; | ||
| 67 | font-size: 7px; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | } |
This diff is collapsed.
Click to expand it.
| 1 | /* **************************************************************************** | ||
| 2 | * MEDIA AREA SCSS FILE | ||
| 3 | */ | ||
| 4 | @import "~@wpmudev/shared-ui/scss/functions"; | ||
| 5 | @import "~@wpmudev/shared-ui/scss/colors"; | ||
| 6 | @import "~@wpmudev/shared-ui/scss/variables"; | ||
| 7 | // Override body class | ||
| 8 | $sui-version: 'smush-media'; | ||
| 9 | $sui-wrap-class: false; | ||
| 10 | @import "~@wpmudev/shared-ui/scss/mixins"; | ||
| 11 | @import "~@wpmudev/shared-ui/scss/tooltips"; | ||
| 12 | |||
| 13 | /* **************************************************************************** | ||
| 14 | * MEDIA AREA STYLES | ||
| 15 | */ | ||
| 16 | |||
| 17 | // Set column width. | ||
| 18 | .manage-column.column-smushit { | ||
| 19 | width: 260px; | ||
| 20 | } | ||
| 21 | |||
| 22 | // Margin for buttons. | ||
| 23 | .sui-smush-media { | ||
| 24 | .button { | ||
| 25 | margin-right: 5px; | ||
| 26 | &:last-of-type { | ||
| 27 | margin-right: 0; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | |||
| 32 | // Smush button loading icon. | ||
| 33 | #ngg-listimages, | ||
| 34 | .column-smushit { | ||
| 35 | .spinner { | ||
| 36 | float: none; | ||
| 37 | |||
| 38 | &.visible { | ||
| 39 | visibility: visible; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | } | ||
| 43 | .smush-status-links{ | ||
| 44 | .smush-upgrade-link { | ||
| 45 | color: #8D00B1; | ||
| 46 | font-size: 12px; | ||
| 47 | } | ||
| 48 | .smush-ignore-utm,.smush-revert-utm{ | ||
| 49 | display: block; | ||
| 50 | margin: 6px 0 4px; | ||
| 51 | } | ||
| 52 | a { | ||
| 53 | text-decoration: none; | ||
| 54 | } | ||
| 55 | span { | ||
| 56 | float: none !important;; | ||
| 57 | } | ||
| 58 | .smush-cdn-notice { | ||
| 59 | color: #50575E; | ||
| 60 | a { | ||
| 61 | color:#2271B1; | ||
| 62 | &:focus { | ||
| 63 | box-shadow: none; | ||
| 64 | opacity: 0.7; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | .smush-status { | ||
| 70 | &.smush-warning,&.smush-ignored,&.smush-success{ | ||
| 71 | padding-left:17px; | ||
| 72 | position: relative; | ||
| 73 | &:before{ | ||
| 74 | content:""; | ||
| 75 | background: url('../images/icon-warning.png' ) no-repeat 0 0; | ||
| 76 | position: absolute; | ||
| 77 | width:12px; | ||
| 78 | height:12px; | ||
| 79 | background-size: contain; | ||
| 80 | left: 0; | ||
| 81 | top:3px; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | &.smush-ignored{ | ||
| 85 | &:before{ | ||
| 86 | background-image: url('../images/icon-ignored.png' ) !important; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | &.smush-success{ | ||
| 90 | &:before{ | ||
| 91 | background-image: url('../images/icon-success.png' ) !important; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | .sui-icon-warning-media-lib { | ||
| 95 | margin-right:4px; | ||
| 96 | position:relative; | ||
| 97 | top:1px; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | .column-smushit .smush-status{ | ||
| 101 | color:#50575E; | ||
| 102 | } | ||
| 103 | // Stats table. | ||
| 104 | .sui-smush-media { | ||
| 105 | table.wp-smush-stats-holder { | ||
| 106 | width: 100%; | ||
| 107 | border: 1px solid #E6E6E6; | ||
| 108 | border-radius: 4px; | ||
| 109 | margin-top: 6px; | ||
| 110 | border-collapse: collapse; | ||
| 111 | border-spacing: 0; | ||
| 112 | thead { | ||
| 113 | th.smush-stats-header { | ||
| 114 | padding: 8px 10px; | ||
| 115 | border-bottom: 1px solid #E6E6E6 !important; | ||
| 116 | color: #32373D; | ||
| 117 | font-size: 12px; | ||
| 118 | font-weight: bold; | ||
| 119 | letter-spacing: -0.23px; | ||
| 120 | line-height: 16px; | ||
| 121 | text-align: left; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | tr { | ||
| 125 | border: 1px solid #E6E6E6; | ||
| 126 | } | ||
| 127 | td { | ||
| 128 | overflow-wrap: break-word; | ||
| 129 | vertical-align: middle; | ||
| 130 | padding: 8px 10px; | ||
| 131 | color: #555555; | ||
| 132 | font-size: 11px; | ||
| 133 | letter-spacing: -0.21px; | ||
| 134 | line-height: 16px; | ||
| 135 | border-bottom: 1px solid #E6E6E6; | ||
| 136 | &:first-of-type { | ||
| 137 | max-width: 110px; | ||
| 138 | font-weight: 500; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | // Override !important set from WordPress. | ||
| 145 | #the-list { | ||
| 146 | .sui-smush-media { | ||
| 147 | thead { | ||
| 148 | th.smush-stats-header { | ||
| 149 | border-bottom: 1px solid #E6E6E6 !important; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | // Responsive table for list mode. | ||
| 156 | @media screen and (max-width: 1024px) { | ||
| 157 | .wp-list-table .smushit { | ||
| 158 | table.wp-smush-stats-holder { | ||
| 159 | th { | ||
| 160 | display: table-cell; | ||
| 161 | box-sizing: border-box; | ||
| 162 | } | ||
| 163 | tr td { | ||
| 164 | word-wrap: break-word; | ||
| 165 | display: table-cell !important; | ||
| 166 | &:first-child { | ||
| 167 | border-right: none; | ||
| 168 | box-sizing: border-box; | ||
| 169 | } | ||
| 170 | &:last-child { | ||
| 171 | box-sizing: border-box; | ||
| 172 | float: none; | ||
| 173 | overflow: visible; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | // NextGen Integration. | ||
| 181 | .iedit .wp-smush-action, | ||
| 182 | .iedit .smush-stats-details { | ||
| 183 | font-size: 11px; | ||
| 184 | } | ||
| 185 | |||
| 186 | /*NextGen Gallery stats*/ | ||
| 187 | #ngg-listimages { | ||
| 188 | table.wp-smush-stats-holder { | ||
| 189 | table-layout: fixed; | ||
| 190 | border: 1px solid lightgray; | ||
| 191 | border-collapse: collapse; | ||
| 192 | width: 100%; | ||
| 193 | td, | ||
| 194 | th { | ||
| 195 | border: 1px solid #CECECE; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | .column-7 { | ||
| 199 | width: 300px; | ||
| 200 | } | ||
| 201 | .spinner { | ||
| 202 | width: auto; | ||
| 203 | padding-left: 30px; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | /** NextGen Gallery tr height, to show the progress bar properly for alternate rows **/ | ||
| 208 | .alternate.iedit { | ||
| 209 | height: 120px; | ||
| 210 | } | ||
| 211 | |||
| 212 | /** Allows to click on button, otherwise row-actions from NextGen interferes **/ | ||
| 213 | .wp-smush-nextgen-send { | ||
| 214 | position: relative; | ||
| 215 | z-index: 2; | ||
| 216 | } |
| 1 | /* **************************************************************************** | ||
| 2 | * MODULE: VARIABLES | ||
| 3 | */ | ||
| 4 | |||
| 5 | $font--path: "../fonts" !default; | ||
| 6 | $img--path: "../images" !default; | ||
| 7 | |||
| 8 | $sui-font-path: '~@wpmudev/shared-ui/dist/fonts/'; | ||
| 9 | |||
| 10 | $summary-image: '#{$img--path}/smush-graphic-dashboard-summary.svg'; | ||
| 11 | |||
| 12 | // Promo banners for free footer | ||
| 13 | $cross-sell-1: 'hummingbird'; | ||
| 14 | $cross-sell-2: 'defender'; | ||
| 15 | $cross-sell-3: 'smartcrawl'; | ||
| 16 | |||
| 17 | $upgrade-image: '../../app/assets/images/hero@2x.png'; | ||
| 18 | $upgrade-image-mobile: '../../app/assets/images/hero.png'; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | /** | ||
| 2 | * Webp styles | ||
| 3 | * | ||
| 4 | * @since 3.8.0 | ||
| 5 | */ | ||
| 6 | |||
| 7 | @include body-class(true) { | ||
| 8 | |||
| 9 | #smush-box-webp-webp { | ||
| 10 | |||
| 11 | .smush-webp-supported-browser { | ||
| 12 | height: 30px; | ||
| 13 | width: 30px; | ||
| 14 | padding: 5px; | ||
| 15 | margin-right: 10px; | ||
| 16 | border-radius: 4px; | ||
| 17 | background-color: #F2F2F2; | ||
| 18 | display: inline-block; | ||
| 19 | |||
| 20 | img { | ||
| 21 | height: 20px; | ||
| 22 | width: 20px; | ||
| 23 | } | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | #smush-box-webp-wizard { | ||
| 28 | .sui-row-with-sidenav { | ||
| 29 | margin-bottom: 0; | ||
| 30 | |||
| 31 | .sui-sidenav { | ||
| 32 | padding: 30px; | ||
| 33 | border-top-left-radius: $border-radius; | ||
| 34 | background-color: #F8F8F8; | ||
| 35 | |||
| 36 | .smush-wizard-bar-subtitle { | ||
| 37 | font-size: 11px; | ||
| 38 | line-height: 20px; | ||
| 39 | font-weight: 700; | ||
| 40 | color: #AAAAAA; | ||
| 41 | text-transform: uppercase; | ||
| 42 | } | ||
| 43 | |||
| 44 | .smush-sidenav-title { | ||
| 45 | display: flex; | ||
| 46 | align-items: center; | ||
| 47 | margin-bottom: 33px; | ||
| 48 | |||
| 49 | h4 { | ||
| 50 | margin: 0; | ||
| 51 | line-height: 20px; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | .smush-wizard-steps-container { | ||
| 56 | |||
| 57 | ul { | ||
| 58 | margin: 0; | ||
| 59 | |||
| 60 | @include media(max-width, lg) { | ||
| 61 | display: flex; | ||
| 62 | flex-direction: row; | ||
| 63 | justify-content: space-between; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | .smush-wizard-bar-step { | ||
| 68 | display: inline-block; | ||
| 69 | font-size: 13px; | ||
| 70 | color: #AAAAAA; | ||
| 71 | line-height: 22px; | ||
| 72 | font-weight: 500; | ||
| 73 | margin-bottom: 0; | ||
| 74 | |||
| 75 | .smush-wizard-bar-step-number { | ||
| 76 | display: inline-block; | ||
| 77 | margin-right: 10px; | ||
| 78 | text-align: center; | ||
| 79 | border-radius: 50%; | ||
| 80 | width: 22px; | ||
| 81 | height: 22px; | ||
| 82 | font-size: 11px; | ||
| 83 | background-color: #F2F2F2; | ||
| 84 | border: 1px solid #DDDDDD; | ||
| 85 | |||
| 86 | @include media(max-width, lg) { | ||
| 87 | display: block; | ||
| 88 | margin: 0 auto 5px auto; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | &.disabled { | ||
| 93 | color: #DDDDDD; | ||
| 94 | } | ||
| 95 | |||
| 96 | &.current { | ||
| 97 | color: #333333; | ||
| 98 | |||
| 99 | .smush-wizard-bar-step-number { | ||
| 100 | background-color: #FFFFFF; | ||
| 101 | border-color: #333333; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | &.done .smush-wizard-bar-step-number { | ||
| 106 | background-color: #1ABC9C; | ||
| 107 | border-color: #1ABC9C; | ||
| 108 | |||
| 109 | .sui-icon-check::before { | ||
| 110 | color: #FFFFFF; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | @include media(min-width, lg) { | ||
| 115 | display: block; | ||
| 116 | } | ||
| 117 | |||
| 118 | @include media(max-width, lg) { | ||
| 119 | width: 70px; | ||
| 120 | text-align: center; | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | svg { | ||
| 125 | |||
| 126 | line { | ||
| 127 | stroke-width: 4px; | ||
| 128 | } | ||
| 129 | |||
| 130 | &.smush-svg-desktop { | ||
| 131 | height: 40px; | ||
| 132 | width: 22px; | ||
| 133 | margin-left: 10px; | ||
| 134 | display: none; | ||
| 135 | |||
| 136 | @include media(min-width, lg) { | ||
| 137 | display: block; | ||
| 138 | } | ||
| 139 | } | ||
| 140 | |||
| 141 | &.smush-svg-mobile { | ||
| 142 | width: 100%; | ||
| 143 | height: 4px; | ||
| 144 | display: block; | ||
| 145 | margin-bottom: -14px; | ||
| 146 | padding: 0 35px; | ||
| 147 | |||
| 148 | @include media(min-width, lg) { | ||
| 149 | display: none; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | @include media(max-width, sm) { | ||
| 156 | padding: 20px; | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | .smush-wizard-steps-content-wrapper { | ||
| 161 | padding: 20px; | ||
| 162 | |||
| 163 | .smush-wizard-steps-content { | ||
| 164 | padding: 0 70px; | ||
| 165 | text-align: center; | ||
| 166 | |||
| 167 | &:first-child { | ||
| 168 | padding-top: 30px; | ||
| 169 | } | ||
| 170 | |||
| 171 | .smush-step-indicator { | ||
| 172 | font-size: 11px; | ||
| 173 | font-weight: 500; | ||
| 174 | color: #888888; | ||
| 175 | } | ||
| 176 | |||
| 177 | h2 { | ||
| 178 | margin: 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | @include media(max-width, sm) { | ||
| 182 | padding: 0; | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | &.smush-wizard-step-1 { | ||
| 187 | |||
| 188 | .sui-box-selectors { | ||
| 189 | padding-left: 115px; | ||
| 190 | padding-right: 115px; | ||
| 191 | margin-bottom: 15px; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | |||
| 195 | &.smush-wizard-step-2 { | ||
| 196 | |||
| 197 | .smush-wizard-rules-wrapper { | ||
| 198 | text-align: left; | ||
| 199 | } | ||
| 200 | |||
| 201 | .sui-tabs-menu { | ||
| 202 | justify-content: center; | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 206 | @include media(min-width, sm) { | ||
| 207 | padding: 30px; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | } | ||
| 212 | } |
This diff is collapsed.
Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
No preview for this file type
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
No preview for this file type
2.04 KB
1.32 KB
2.35 KB
2.56 KB
1.15 KB
2.62 KB
19.9 KB
158 KB
265 Bytes
26.2 KB
692 Bytes
322 Bytes
1.01 KB
776 Bytes
304 Bytes
23.7 KB
390 Bytes
264 Bytes
655 Bytes
1.18 KB
3.18 KB
This diff is collapsed.
Click to expand it.
13.5 KB
34.3 KB
90.1 KB
221 KB
594 Bytes
652 Bytes
558 Bytes
5.81 KB
5.8 KB
2.03 KB
4.15 KB
2.23 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-auto@2x.png
0 → 100644
5.64 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-lazy_load.png
0 → 100644
5.01 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-lazy_load@2x.png
0 → 100644
13.9 KB
3.34 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-lossy@2x.png
0 → 100644
6.75 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-original.png
0 → 100644
4.52 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-original@2x.png
0 → 100644
9.04 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-strip_exif.png
0 → 100644
2.23 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-strip_exif@2x.png
0 → 100644
4.76 KB
17.5 KB
wp-content/plugins/wp-smushit/app/assets/images/onboarding/graphic-onboarding-usage@2x.png
0 → 100644
42.2 KB
16.3 KB
37.1 KB
991 Bytes
3.97 KB
8.45 KB
86 KB
11.6 KB
45.1 KB
4.21 KB
70.1 KB
308 Bytes
545 Bytes
713 Bytes
This diff is collapsed.
Click to expand it.
13.8 KB
30.3 KB
62.4 KB
5.71 KB
4.75 KB
6.46 KB
2.95 KB
4.75 KB
995 Bytes
201 KB
469 Bytes
No preview for this file type
363 Bytes
13.4 KB
27.7 KB
852 Bytes
852 Bytes
4.46 KB
9.04 KB
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/fonts/wpmudev-close-icon.eot
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/fonts/wpmudev-close-icon.svg
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/fonts/wpmudev-close-icon.ttf
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/fonts/wpmudev-close-icon.woff
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/fonts/wpmudev-close-icon.woff2
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-defender.png
0 → 100644
12.4 KB
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-forminator.png
0 → 100644
11.7 KB
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-hummingbird.png
0 → 100644
13.7 KB
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-hustle.png
0 → 100644
16.3 KB
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-smartcrawl.png
0 → 100644
12.7 KB
wp-content/plugins/wp-smushit/core/external/plugin-notice/assets/images/plugins-smush.png
0 → 100644
18.2 KB
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/core/modules/background/class-background-logger-container.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/core/modules/background/class-background-process-status.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff could not be displayed because it is too large.
wp-content/plugins/wp-smushit/readme.txt
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/uninstall.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/classes/Base_MixpanelBase.html
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
No preview for this file type
This diff is collapsed.
Click to expand it.
No preview for this file type
No preview for this file type
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/files/Base.MixpanelBase.html
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/files/Base/MixpanelBase.php.txt
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/files/Producers.MixpanelEvents.html
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/files/Producers.MixpanelPeople.html
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
No preview for this file type
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/font/fontawesome-webfont.eot
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/font/fontawesome-webfont.svg
0 → 100644
This diff could not be displayed because it is too large.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/font/fontawesome-webfont.ttf
0 → 100644
No preview for this file type
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/font/fontawesome-webfont.woff
0 → 100644
No preview for this file type
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/apple-touch-icon-114x114.png
0 → 100644
27.7 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/apple-touch-icon-72x72.png
0 → 100644
12.5 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/apple-touch-icon.png
0 → 100644
8.16 KB
This diff is collapsed.
Click to expand it.
No preview for this file type
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/hierarchy-item.png
0 → 100644
236 Bytes
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/icon-class-13x13.png
0 → 100644
428 Bytes
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/icon-interface-13x13.png
0 → 100644
308 Bytes
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/icon-interface.svg
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/icon-trait-13x13.png
0 → 100644
340 Bytes
This diff is collapsed.
Click to expand it.
No preview for this file type
No preview for this file type
1.46 KB
1.45 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/iviewer/iviewer.zoom_fit.png
0 → 100644
1.22 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/iviewer/iviewer.zoom_in.png
0 → 100644
1.39 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/iviewer/iviewer.zoom_out.png
0 → 100644
1.38 KB
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/images/iviewer/iviewer.zoom_zero.png
0 → 100644
1.07 KB
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/js/jquery.dotdotdot-1.5.9.js
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/js/jquery.dotdotdot-1.5.9.min.js
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/js/jquery.smooth-scroll.js
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/docs/js/ui/1.10.4/jquery-ui.min.js
0 → 100644
This diff could not be displayed because it is too large.
This diff is collapsed.
Click to expand it.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/examples/consumers/ObConsumer.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/CurlConsumer.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/FileConsumer.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/ConsumerStrategies/SocketConsumer.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelBaseProducer.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelEvents.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelGroups.php
0 → 100644
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/lib/Producers/MixpanelPeople.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/vendor/mixpanel/mixpanel-php/test/Base/MixpanelBaseProducerTest.php
0 → 100644
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
This diff is collapsed.
Click to expand it.
wp-content/plugins/wp-smushit/wp-smush.php
0 → 100644
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment