This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,11 @@
import lazySizes from 'lazysizes';
import 'lazysizes/plugins/native-loading/ls.native-loading';
lazySizes.cfg.nativeLoading = {
setLoadingAttribute: true,
disableListeners: {
scroll: true,
},
};
lazySizes.init();

View File

@ -0,0 +1,3 @@
import lazySizes from 'lazysizes';
lazySizes.init();

View File

@ -0,0 +1,362 @@
import '../../scss/resize-detection.scss';
/**
* Image resize detection (IRD).
*
* Show all wrongly scaled images with a highlighted border and resize box.
*
* Made in pure JS.
* DO NOT ADD JQUERY SUPPORT!!!
*
* @since 2.9
*/
( function() {
'use strict';
const SmushIRS = {
bar: document.getElementById( 'smush-image-bar' ),
toggle: document.getElementById( 'smush-image-bar-toggle' ),
images: {
bigger: [],
smaller: [],
},
strings: window.wp_smush_resize_vars,
/**
* Init scripts.
*/
init() {
/**
* Make sure these are set, before we proceed.
*/
if ( ! this.bar ) {
this.bar = document.getElementById( 'smush-image-bar' );
}
if ( ! this.toggle ) {
this.toggle = document.getElementById(
'smush-image-bar-toggle'
);
}
this.process();
// Register the event handler after everything is done.
this.toggle.addEventListener(
'click',
this.handleToggleClick.bind( this )
);
},
/**
* Do image processing.
*/
process() {
const icon = this.toggle.querySelector( 'i' );
icon.classList.add( 'sui-icon-loader' );
icon.classList.remove( 'sui-icon-info' );
this.detectImages();
if ( ! this.images.bigger.length && ! this.images.smaller.length ) {
this.toggle.classList.add( 'smush-toggle-success' );
document.getElementById(
'smush-image-bar-notice'
).style.display = 'block';
document.getElementById(
'smush-image-bar-notice-desc'
).style.display = 'none';
} else {
this.toggle.classList.remove( 'smush-toggle-success' );
document.getElementById(
'smush-image-bar-notice'
).style.display = 'none';
document.getElementById(
'smush-image-bar-notice-desc'
).style.display = 'block';
this.generateMarkup( 'bigger' );
this.generateMarkup( 'smaller' );
}
this.toggleDivs();
icon.classList.remove( 'sui-icon-loader' );
icon.classList.add( 'sui-icon-info' );
},
/**
* Various checks to see if the image should be processed.
*
* @param {Object} image
* @return {boolean} Should skip image or not.
*/
shouldSkipImage( image ) {
// Skip avatars.
if ( image.classList.contains( 'avatar' ) ) {
return true;
}
// Skip images from Smush CDN with auto-resize feature.
if (
'string' === typeof image.getAttribute( 'no-resize-detection' )
) {
return true;
}
// Skip 1x1px images.
if (
image.clientWidth === image.clientHeight &&
1 === image.clientWidth
) {
return true;
}
// Skip 1x1px placeholders.
if (
image.naturalWidth === image.naturalHeight &&
1 === image.naturalWidth
) {
return true;
}
// If width attribute is not set, do not continue.
return null === image.clientWidth || null === image.clientHeight;
},
/**
* Get tooltip text.
*
* @param {Object} props
* @return {string} Tooltip.
*/
getTooltipText( props ) {
let tooltipText = '';
if ( props.bigger_width || props.bigger_height ) {
/** @param {string} strings.large_image */
tooltipText = this.strings.large_image;
} else if ( props.smaller_width || props.smaller_height ) {
/** @param {string} strings.small_image */
tooltipText = this.strings.small_image;
}
return tooltipText
.replace( 'width', props.real_width )
.replace( 'height', props.real_height );
},
/**
* Generate markup.
*
* @param {string} type Accepts: 'bigger' or 'smaller'.
*/
generateMarkup( type ) {
this.images[ type ].forEach( ( image, index ) => {
const item = document.createElement( 'div' ),
tooltip = this.getTooltipText( image.props );
item.setAttribute(
'class',
'smush-resize-box smush-tooltip smush-tooltip-constrained'
);
item.setAttribute( 'data-tooltip', tooltip );
item.setAttribute( 'data-image', image.class );
item.addEventListener( 'click', ( e ) =>
this.highlightImage( e )
);
item.innerHTML = `
<div class="smush-image-info">
<span>${ index + 1 }</span>
<span class="smush-tag">${ image.props.computed_width } x ${ image.props.computed_height }px</span>
<i class="smush-front-icons smush-front-icon-arrows-in" aria-hidden="true">&nbsp;</i>
<span class="smush-tag smush-tag-success">${ image.props.real_width } × ${ image.props.real_height }px</span>
</div>
<div class="smush-image-description">${ tooltip }</div>
`;
document
.getElementById( 'smush-image-bar-items-' + type )
.appendChild( item );
} );
},
/**
* Show/hide sections based on images.
*/
toggleDivs() {
const types = [ 'bigger', 'smaller' ];
types.forEach( ( type ) => {
const div = document.getElementById(
'smush-image-bar-items-' + type
);
if ( 0 === this.images[ type ].length ) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
} );
},
/**
* Scroll the selected image into view and highlight it.
*
* @param {Object} e
*/
highlightImage( e ) {
this.removeSelection();
const el = document.getElementsByClassName(
e.currentTarget.dataset.image
);
if ( 'undefined' !== typeof el[ 0 ] ) {
// Display description box.
e.currentTarget.classList.toggle( 'show-description' );
// Scroll and flash image.
el[ 0 ].scrollIntoView( {
behavior: 'smooth',
block: 'center',
inline: 'nearest',
} );
el[ 0 ].style.opacity = '0.5';
setTimeout( () => {
el[ 0 ].style.opacity = '1';
}, 1000 );
}
},
/**
* Handle click on the toggle item.
*/
handleToggleClick() {
this.bar.classList.toggle( 'closed' );
this.toggle.classList.toggle( 'closed' );
this.removeSelection();
},
/**
* Remove selected items.
*/
removeSelection() {
const items = document.getElementsByClassName( 'show-description' );
if ( items.length > 0 ) {
Array.from( items ).forEach( ( div ) =>
div.classList.remove( 'show-description' )
);
}
},
/**
* Function to highlight all scaled images.
*
* Add yellow border and then show one small box to
* resize the images as per the required size, on fly.
*/
detectImages() {
const images = document.getElementsByTagName( 'img' );
for ( const image of images ) {
if ( this.shouldSkipImage( image ) ) {
continue;
}
// Get defined width and height.
const props = {
real_width: image.clientWidth,
real_height: image.clientHeight,
computed_width: image.naturalWidth,
computed_height: image.naturalHeight,
bigger_width: image.clientWidth * 1.5 < image.naturalWidth,
bigger_height:
image.clientHeight * 1.5 < image.naturalHeight,
smaller_width: image.clientWidth > image.naturalWidth,
smaller_height: image.clientHeight > image.naturalHeight,
};
// In case image is in correct size, do not continue.
if (
! props.bigger_width &&
! props.bigger_height &&
! props.smaller_width &&
! props.smaller_height
) {
continue;
}
const imgType =
props.bigger_width || props.bigger_height
? 'bigger'
: 'smaller',
imageClass =
'smush-image-' + ( this.images[ imgType ].length + 1 );
// Fill the images arrays.
this.images[ imgType ].push( {
src: image,
props,
class: imageClass,
} );
/**
* Add class to original image.
* Can't add two classes in single add(), because no support in IE11.
* image.classList.add('smush-detected-img', imageClass);
*/
image.classList.add( 'smush-detected-img' );
image.classList.add( imageClass );
}
}, // End detectImages()
/**
* Allows refreshing the list. A good way is to refresh on lazyload actions.
*
* @since 3.6.0
*/
refresh() {
// Clear out classes on DOM.
for ( let id in this.images.bigger ) {
if ( this.images.bigger.hasOwnProperty( id ) ) {
this.images.bigger[ id ].src.classList.remove(
'smush-detected-img'
);
this.images.bigger[ id ].src.classList.remove(
'smush-image-' + ++id
);
}
}
for ( let id in this.images.smaller ) {
if ( this.images.smaller.hasOwnProperty( id ) ) {
this.images.smaller[ id ].src.classList.remove(
'smush-detected-img'
);
this.images.smaller[ id ].src.classList.remove(
'smush-image-' + ++id
);
}
}
this.images = {
bigger: [],
smaller: [],
};
// This might be overkill - there will probably never be a situation when there are less images than on
// initial page load.
const elements = document.getElementsByClassName(
'smush-resize-box'
);
while ( elements.length > 0 ) {
elements[ 0 ].remove();
}
this.process();
},
}; // End WP_Smush_IRS
/**
* After page load, initialize toggle event.
*/
window.addEventListener( 'DOMContentLoaded', () => SmushIRS.init() );
window.addEventListener( 'lazyloaded', () => SmushIRS.refresh() );
}() );