Add X13 WebP module for image conversion to next-generation formats
- Implemented the X13Webp class with core functionalities for converting images to WebP format. - Added support for different PHP versions and defined constants for versioning. - Included translation strings for various user interface elements and messages. - Created XML file for module versioning.
This commit is contained in:
56
modules/x13webp/views/js/front/x13webp.front.js
Normal file
56
modules/x13webp/views/js/front/x13webp.front.js
Normal file
@@ -0,0 +1,56 @@
|
||||
$(document).ready(() => {
|
||||
let x13images = [];
|
||||
|
||||
$("img").each(function () {
|
||||
const imgSrc = $(this).attr("data-src") ?? $(this).attr("data-original") ?? $(this).attr("src");
|
||||
|
||||
if (!imgSrc) return;
|
||||
if (imgSrc.includes(".webp")) return;
|
||||
|
||||
if ($(this).siblings("source").length && $(this).siblings("source").attr("srcset") !== undefined) {
|
||||
if ($(this).siblings("source").attr("srcset").includes(".webp")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
x13images.push(imgSrc.trim());
|
||||
});
|
||||
|
||||
$("[style]").each(function () {
|
||||
const bgImage = $(this).css("background-image");
|
||||
|
||||
if (bgImage.includes(".webp") || (!bgImage.includes(".jpg") && !bgImage.includes(".png"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
let image = $(this)
|
||||
.css("background-image")
|
||||
.replace(/url\("([^"]+)"\)/, "$1");
|
||||
x13images.push(image.trim());
|
||||
});
|
||||
|
||||
$("#product #thumbs_list a.fancybox").each(function () {
|
||||
const href = $(this).attr("href");
|
||||
if (href.length) {
|
||||
x13images.push(href.trim());
|
||||
}
|
||||
});
|
||||
$("#product .images-container .thumb").each(function () {
|
||||
const medium = $(this).data("image-medium-src");
|
||||
const large = $(this).data("image-large-src");
|
||||
if (typeof medium !== 'undefined') {
|
||||
x13images.push(medium.trim());
|
||||
}
|
||||
if (typeof large !== 'undefined') {
|
||||
x13images.push(large.trim());
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: x13webp_ajax_convert_url,
|
||||
method: "POST",
|
||||
data: {
|
||||
x13images,
|
||||
},
|
||||
});
|
||||
});
|
||||
171
modules/x13webp/views/js/front/x13webp.picture.js
Normal file
171
modules/x13webp/views/js/front/x13webp.picture.js
Normal file
@@ -0,0 +1,171 @@
|
||||
$(() => {
|
||||
x13webp.fixProductThumbs();
|
||||
if (!x13webpIsPs16) {
|
||||
x13webp.addStylesheet();
|
||||
}
|
||||
x13webp.observe();
|
||||
});
|
||||
|
||||
$(window).on('hashchange', function () {
|
||||
if (!x13webpIsPs16) return;
|
||||
|
||||
setTimeout(function () {
|
||||
let thumb = $('#thumbs_list_frame li:visible:first');
|
||||
if (thumb.length === 0) return;
|
||||
if (thumb.find('picture').length === 0) return;
|
||||
|
||||
let img = thumb.find('img').attr('data-original') ?? thumb.find('img').attr('src');
|
||||
let source = thumb.find('source').attr('srcset');
|
||||
|
||||
$('#' + x13webp.themeSelectors.jsQvProductCover).attr('src', img.replace('-cart_default', '-large_default'));
|
||||
$('#' + x13webp.themeSelectors.jsQvProductCover).siblings('source').attr('srcset', source.replace('-cart_default', '-large_default'));
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
const x13webp = {
|
||||
themeSelectors: {
|
||||
jsQvProductCover: x13webpIsPs16 ? "bigpic" : "js-qv-product-cover",
|
||||
jsModalProductCover: "js-modal-product-cover",
|
||||
jsThumb: "js-thumb",
|
||||
jsModalThumb: "js-modal-thumb",
|
||||
},
|
||||
|
||||
addStylesheet: () => {
|
||||
let thumbHover = "." + x13webp.themeSelectors.jsThumb + ":hover";
|
||||
let thumbSelected = "." + x13webp.themeSelectors.jsThumb + ".selected";
|
||||
let thumb = document.querySelector(thumbSelected);
|
||||
|
||||
if (!thumb) return;
|
||||
|
||||
thumb = getComputedStyle(thumb);
|
||||
let thumbBorder = {
|
||||
style: thumb.borderBlockStyle,
|
||||
width: thumb.borderBlockWidth,
|
||||
color: thumb.borderBlockColor,
|
||||
};
|
||||
|
||||
let css =
|
||||
"picture" +
|
||||
thumbSelected +
|
||||
", picture" +
|
||||
thumbHover +
|
||||
", " +
|
||||
"picture" +
|
||||
thumbSelected.replace(
|
||||
x13webp.themeSelectors.jsThumb,
|
||||
x13webp.themeSelectors.jsModalThumb
|
||||
) +
|
||||
", picture" +
|
||||
thumbHover.replace(
|
||||
x13webp.themeSelectors.jsThumb,
|
||||
x13webp.themeSelectors.jsModalThumb
|
||||
) +
|
||||
" { border: none !important; outline-style: " +
|
||||
thumbBorder.style +
|
||||
" !important; outline-color: " +
|
||||
thumbBorder.color +
|
||||
" !important; outline-width: " +
|
||||
thumbBorder.width +
|
||||
" !important; outline-offset: -" +
|
||||
thumbBorder.width +
|
||||
" !important;}",
|
||||
head = document.head || document.getElementsByTagName("head")[0],
|
||||
style = document.createElement("style");
|
||||
|
||||
head.appendChild(style);
|
||||
|
||||
style.type = "text/css";
|
||||
if (style.styleSheet) {
|
||||
// This is required for IE8 and below.
|
||||
style.styleSheet.cssText = css;
|
||||
} else {
|
||||
style.appendChild(document.createTextNode(css));
|
||||
}
|
||||
},
|
||||
|
||||
replacePictureSource: (target, source) => {
|
||||
target.setAttribute("srcset", source);
|
||||
},
|
||||
|
||||
addAttributesToPicture: (target, classArray, dataArray = {}) => {
|
||||
target.style.display = "inline-block";
|
||||
target.classList.add(...classArray);
|
||||
|
||||
Object.entries(dataArray).forEach(([key, value]) => {
|
||||
target.dataset[key] = value;
|
||||
});
|
||||
},
|
||||
|
||||
fixProductThumbs: () => {
|
||||
const body = document.querySelector("body").getAttribute("id");
|
||||
|
||||
if (body !== "product") return;
|
||||
|
||||
const thumbs = [
|
||||
...document.querySelectorAll("." + x13webp.themeSelectors.jsThumb),
|
||||
];
|
||||
const modalThumbs = [
|
||||
...document.querySelectorAll("." + x13webp.themeSelectors.jsModalThumb),
|
||||
];
|
||||
|
||||
const allThumbs = [...thumbs, ...modalThumbs];
|
||||
|
||||
allThumbs.forEach((thumb) => {
|
||||
if (!thumb.parentElement) return;
|
||||
if (thumb.parentElement.tagName !== "PICTURE") return;
|
||||
|
||||
const target = thumb.parentElement;
|
||||
const classArray = thumb.classList;
|
||||
const isModal = classArray.contains(x13webp.themeSelectors.jsModalThumb);
|
||||
const dataArray = Object.assign({}, thumb.dataset);
|
||||
|
||||
x13webp.addAttributesToPicture(target, classArray, dataArray);
|
||||
|
||||
thumb.className = isModal
|
||||
? x13webp.themeSelectors.jsModalThumb + "-fix"
|
||||
: x13webp.themeSelectors.jsThumb + "-fix";
|
||||
});
|
||||
},
|
||||
|
||||
observe: () => {
|
||||
const pictureTagObserver = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (!mutation.target.parentElement) return;
|
||||
if (mutation.target.parentElement.tagName !== "PICTURE") return;
|
||||
|
||||
const mutationClass = mutation.target.classList;
|
||||
|
||||
if (
|
||||
mutationClass.contains(x13webp.themeSelectors.jsQvProductCover) ||
|
||||
mutationClass.contains(x13webp.themeSelectors.jsModalProductCover) ||
|
||||
mutation.target.getAttribute("id") ===
|
||||
x13webp.themeSelectors.jsQvProductCover
|
||||
) {
|
||||
const target = mutation.target.parentElement.querySelector("source");
|
||||
let source =
|
||||
mutation.target.getAttribute("data-original") ??
|
||||
mutation.target.getAttribute("src");
|
||||
source = source.replace(/(\.jpg)|(\.png)/, ".webp");
|
||||
|
||||
x13webp.replacePictureSource(target, source);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mutationClass.contains(x13webp.themeSelectors.jsThumb + "-fix")) {
|
||||
const target = mutation.target.parentElement;
|
||||
const classArray = mutation.target.classList;
|
||||
|
||||
x13webp.addAttributesToPicture(target, classArray);
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const allPictureTags = document.querySelectorAll("img");
|
||||
|
||||
allPictureTags.forEach((pictureTag) => {
|
||||
pictureTagObserver.observe(pictureTag, { attributes: true });
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user