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